Browse Source

Allow for the Painless Definition to have multiple instances (#27096)

Jack Conradson 8 years ago
parent
commit
dda5d1af29
53 changed files with 611 additions and 607 deletions
  1. 249 266
      modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java
  2. 84 57
      modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java
  3. 3 3
      modules/lang-painless/src/main/java/org/elasticsearch/painless/Locals.java
  4. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java
  5. 2 2
      modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngine.java
  6. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java
  7. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java
  8. 2 2
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java
  9. 24 22
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EAssignment.java
  10. 26 25
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java
  11. 3 3
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java
  12. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java
  13. 3 4
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECapturingFunctionRef.java
  14. 16 16
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java
  15. 2 2
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java
  16. 9 9
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java
  17. 2 2
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java
  18. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EElvis.java
  19. 3 4
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EFunctionRef.java
  20. 3 3
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java
  21. 6 9
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ELambda.java
  22. 2 2
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EListInit.java
  23. 3 3
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EMapInit.java
  24. 1 2
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewArray.java
  25. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java
  26. 7 7
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java
  27. 5 4
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ERegex.java
  28. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EString.java
  29. 5 5
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java
  30. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java
  31. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubArrayLength.java
  32. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubBrace.java
  33. 5 4
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefArray.java
  34. 2 2
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefCall.java
  35. 5 5
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefField.java
  36. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubListShortcut.java
  37. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java
  38. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java
  39. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIf.java
  40. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java
  41. 2 2
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachArray.java
  42. 3 2
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachIterable.java
  43. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java
  44. 1 1
      modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java
  45. 41 48
      modules/lang-painless/src/test/java/org/elasticsearch/painless/AnalyzerCasterTests.java
  46. 22 22
      modules/lang-painless/src/test/java/org/elasticsearch/painless/BaseClassTests.java
  47. 1 1
      modules/lang-painless/src/test/java/org/elasticsearch/painless/DebugTests.java
  48. 1 1
      modules/lang-painless/src/test/java/org/elasticsearch/painless/Debugger.java
  49. 32 32
      modules/lang-painless/src/test/java/org/elasticsearch/painless/DefBootstrapTests.java
  50. 11 11
      modules/lang-painless/src/test/java/org/elasticsearch/painless/OrTests.java
  51. 2 1
      modules/lang-painless/src/test/java/org/elasticsearch/painless/PainlessDocGenerator.java
  52. 1 1
      modules/lang-painless/src/test/java/org/elasticsearch/painless/ScriptTestCase.java
  53. 6 6
      modules/lang-painless/src/test/java/org/elasticsearch/painless/node/NodeToStringTests.java

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

@@ -24,34 +24,19 @@ import org.elasticsearch.painless.Definition.Type;
 
 import java.util.Objects;
 
-import static org.elasticsearch.painless.Definition.BOOLEAN_OBJ_TYPE;
-import static org.elasticsearch.painless.Definition.BOOLEAN_TYPE;
-import static org.elasticsearch.painless.Definition.BYTE_OBJ_TYPE;
-import static org.elasticsearch.painless.Definition.BYTE_TYPE;
-import static org.elasticsearch.painless.Definition.CHAR_OBJ_TYPE;
-import static org.elasticsearch.painless.Definition.CHAR_TYPE;
-import static org.elasticsearch.painless.Definition.DEF_TYPE;
-import static org.elasticsearch.painless.Definition.DOUBLE_OBJ_TYPE;
-import static org.elasticsearch.painless.Definition.DOUBLE_TYPE;
-import static org.elasticsearch.painless.Definition.FLOAT_OBJ_TYPE;
-import static org.elasticsearch.painless.Definition.FLOAT_TYPE;
-import static org.elasticsearch.painless.Definition.INT_OBJ_TYPE;
-import static org.elasticsearch.painless.Definition.INT_TYPE;
-import static org.elasticsearch.painless.Definition.LONG_OBJ_TYPE;
-import static org.elasticsearch.painless.Definition.LONG_TYPE;
-import static org.elasticsearch.painless.Definition.NUMBER_TYPE;
-import static org.elasticsearch.painless.Definition.OBJECT_TYPE;
-import static org.elasticsearch.painless.Definition.SHORT_OBJ_TYPE;
-import static org.elasticsearch.painless.Definition.SHORT_TYPE;
-import static org.elasticsearch.painless.Definition.STRING_TYPE;
-
 /**
  * Used during the analysis phase to collect legal type casts and promotions
  * for type-checking and later to write necessary casts in the bytecode.
  */
 public final class AnalyzerCaster {
 
-    public static Cast getLegalCast(Location location, Type actual, Type expected, boolean explicit, boolean internal) {
+    private Definition definition;
+
+    public AnalyzerCaster(Definition definition) {
+        this.definition = definition;
+    }
+
+    public Cast getLegalCast(Location location, Type actual, Type expected, boolean explicit, boolean internal) {
         Objects.requireNonNull(actual);
         Objects.requireNonNull(expected);
 
@@ -61,421 +46,421 @@ public final class AnalyzerCaster {
 
         if (actual.dynamic) {
             if (expected.clazz == boolean.class) {
-                return new Cast(DEF_TYPE, BOOLEAN_OBJ_TYPE, explicit, null, BOOLEAN_TYPE, null, null);
+                return new Cast(definition.DefType, definition.BooleanType, explicit, null, definition.booleanType, null, null);
             } else if (expected.clazz == byte.class) {
-                return new Cast(DEF_TYPE, BYTE_OBJ_TYPE, explicit, null, BYTE_TYPE, null, null);
+                return new Cast(definition.DefType, definition.ByteType, explicit, null, definition.byteType, null, null);
             } else if (expected.clazz == short.class) {
-                return new Cast(DEF_TYPE, SHORT_OBJ_TYPE, explicit, null, SHORT_TYPE, null, null);
+                return new Cast(definition.DefType, definition.ShortType, explicit, null, definition.shortType, null, null);
             } else if (expected.clazz == char.class) {
-                return new Cast(DEF_TYPE, CHAR_OBJ_TYPE, explicit, null, CHAR_TYPE, null, null);
+                return new Cast(definition.DefType, definition.CharacterType, explicit, null, definition.charType, null, null);
             } else if (expected.clazz == int.class) {
-                return new Cast(DEF_TYPE, INT_OBJ_TYPE, explicit, null, INT_TYPE, null, null);
+                return new Cast(definition.DefType, definition.IntegerType, explicit, null, definition.intType, null, null);
             } else if (expected.clazz == long.class) {
-                return new Cast(DEF_TYPE, LONG_OBJ_TYPE, explicit, null, LONG_TYPE, null, null);
+                return new Cast(definition.DefType, definition.LongType, explicit, null, definition.longType, null, null);
             } else if (expected.clazz == float.class) {
-                return new Cast(DEF_TYPE, FLOAT_OBJ_TYPE, explicit, null, FLOAT_TYPE, null, null);
+                return new Cast(definition.DefType, definition.FloatType, explicit, null, definition.floatType, null, null);
             } else if (expected.clazz == double.class) {
-                return new Cast(DEF_TYPE, DOUBLE_OBJ_TYPE, explicit, null, DOUBLE_TYPE, null, null);
+                return new Cast(definition.DefType, definition.DoubleType, explicit, null, definition.doubleType, null, null);
             }
         } else if (actual.clazz == Object.class) {
             if (expected.clazz == byte.class && explicit && internal) {
-                return new Cast(OBJECT_TYPE, BYTE_OBJ_TYPE, true, null, BYTE_TYPE, null, null);
+                return new Cast(definition.ObjectType, definition.ByteType, true, null, definition.byteType, null, null);
             } else if (expected.clazz == short.class && explicit && internal) {
-                return new Cast(OBJECT_TYPE, SHORT_OBJ_TYPE, true, null, SHORT_TYPE, null, null);
+                return new Cast(definition.ObjectType, definition.ShortType, true, null, definition.shortType, null, null);
             } else if (expected.clazz == char.class && explicit && internal) {
-                return new Cast(OBJECT_TYPE, CHAR_OBJ_TYPE, true, null, CHAR_TYPE, null, null);
+                return new Cast(definition.ObjectType, definition.CharacterType, true, null, definition.charType, null, null);
             } else if (expected.clazz == int.class && explicit && internal) {
-                return new Cast(OBJECT_TYPE, INT_OBJ_TYPE, true, null, INT_TYPE, null, null);
+                return new Cast(definition.ObjectType, definition.IntegerType, true, null, definition.intType, null, null);
             } else if (expected.clazz == long.class && explicit && internal) {
-                return new Cast(OBJECT_TYPE, LONG_OBJ_TYPE, true, null, LONG_TYPE, null, null);
+                return new Cast(definition.ObjectType, definition.LongType, true, null, definition.longType, null, null);
             } else if (expected.clazz == float.class && explicit && internal) {
-                return new Cast(OBJECT_TYPE, FLOAT_OBJ_TYPE, true, null, FLOAT_TYPE, null, null);
+                return new Cast(definition.ObjectType, definition.FloatType, true, null, definition.floatType, null, null);
             } else if (expected.clazz == double.class && explicit && internal) {
-                return new Cast(OBJECT_TYPE, DOUBLE_OBJ_TYPE, true, null, DOUBLE_TYPE, null, null);
+                return new Cast(definition.ObjectType, definition.DoubleType, true, null, definition.doubleType, null, null);
             }
         } else if (actual.clazz == Number.class) {
             if (expected.clazz == byte.class && explicit && internal) {
-                return new Cast(NUMBER_TYPE, BYTE_OBJ_TYPE, true, null, BYTE_TYPE, null, null);
+                return new Cast(definition.NumberType, definition.ByteType, true, null, definition.byteType, null, null);
             } else if (expected.clazz == short.class && explicit && internal) {
-                return new Cast(NUMBER_TYPE, SHORT_OBJ_TYPE, true, null, SHORT_TYPE, null, null);
+                return new Cast(definition.NumberType, definition.ShortType, true, null, definition.shortType, null, null);
             } else if (expected.clazz == char.class && explicit && internal) {
-                return new Cast(NUMBER_TYPE, CHAR_OBJ_TYPE, true, null, CHAR_TYPE, null, null);
+                return new Cast(definition.NumberType, definition.CharacterType, true, null, definition.charType, null, null);
             } else if (expected.clazz == int.class && explicit && internal) {
-                return new Cast(NUMBER_TYPE, INT_OBJ_TYPE, true, null, INT_TYPE, null, null);
+                return new Cast(definition.NumberType, definition.IntegerType, true, null, definition.intType, null, null);
             } else if (expected.clazz == long.class && explicit && internal) {
-                return new Cast(NUMBER_TYPE, LONG_OBJ_TYPE, true, null, LONG_TYPE, null, null);
+                return new Cast(definition.NumberType, definition.LongType, true, null, definition.longType, null, null);
             } else if (expected.clazz == float.class && explicit && internal) {
-                return new Cast(NUMBER_TYPE, FLOAT_OBJ_TYPE, true, null, FLOAT_TYPE, null, null);
+                return new Cast(definition.NumberType, definition.FloatType, true, null, definition.floatType, null, null);
             } else if (expected.clazz == double.class && explicit && internal) {
-                return new Cast(NUMBER_TYPE, DOUBLE_OBJ_TYPE, true, null, DOUBLE_TYPE, null, null);
+                return new Cast(definition.NumberType, definition.DoubleType, true, null, definition.doubleType, null, null);
             }
         } else if (actual.clazz == String.class) {
             if (expected.clazz == char.class && explicit) {
-                return new Cast(STRING_TYPE, CHAR_TYPE, true);
+                return new Cast(definition.StringType, definition.charType, true);
             }
         } else if (actual.clazz == boolean.class) {
             if (expected.dynamic) {
-                return new Cast(BOOLEAN_OBJ_TYPE, DEF_TYPE, explicit, null, null, BOOLEAN_TYPE, null);
+                return new Cast(definition.BooleanType, definition.DefType, explicit, null, null, definition.booleanType, null);
             } else if (expected.clazz == Object.class && internal) {
-                return new Cast(BOOLEAN_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, BOOLEAN_TYPE, null);
+                return new Cast(definition.BooleanType, definition.ObjectType, explicit, null, null, definition.booleanType, null);
             } else if (expected.clazz == Boolean.class && internal) {
-                return new Cast(BOOLEAN_TYPE, BOOLEAN_TYPE, explicit, null, null, null, BOOLEAN_TYPE);
+                return new Cast(definition.booleanType, definition.booleanType, explicit, null, null, null, definition.booleanType);
             }
         } else if (actual.clazz == byte.class) {
             if (expected.dynamic) {
-                return new Cast(BYTE_OBJ_TYPE, DEF_TYPE, explicit, null, null, BYTE_TYPE, null);
+                return new Cast(definition.ByteType, definition.DefType, explicit, null, null, definition.byteType, null);
             } else if (expected.clazz == Object.class && internal) {
-                return new Cast(BYTE_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, BYTE_TYPE, null);
+                return new Cast(definition.ByteType, definition.ObjectType, explicit, null, null, definition.byteType, null);
             } else if (expected.clazz == Number.class && internal) {
-                return new Cast(BYTE_OBJ_TYPE, NUMBER_TYPE, explicit, null, null, BYTE_TYPE, null);
+                return new Cast(definition.ByteType, definition.NumberType, explicit, null, null, definition.byteType, null);
             } else if (expected.clazz == short.class) {
-                return new Cast(BYTE_TYPE, SHORT_TYPE, explicit);
+                return new Cast(definition.byteType, definition.shortType, explicit);
             } else if (expected.clazz == char.class && explicit) {
-                return new Cast(BYTE_TYPE, CHAR_TYPE, true);
+                return new Cast(definition.byteType, definition.charType, true);
             } else if (expected.clazz == int.class) {
-                return new Cast(BYTE_TYPE, INT_TYPE, explicit);
+                return new Cast(definition.byteType, definition.intType, explicit);
             } else if (expected.clazz == long.class) {
-                return new Cast(BYTE_TYPE, LONG_TYPE, explicit);
+                return new Cast(definition.byteType, definition.longType, explicit);
             } else if (expected.clazz == float.class) {
-                return new Cast(BYTE_TYPE, FLOAT_TYPE, explicit);
+                return new Cast(definition.byteType, definition.floatType, explicit);
             } else if (expected.clazz == double.class) {
-                return new Cast(BYTE_TYPE, DOUBLE_TYPE, explicit);
+                return new Cast(definition.byteType, definition.doubleType, explicit);
             } else if (expected.clazz == Byte.class && internal) {
-                return new Cast(BYTE_TYPE, BYTE_TYPE, explicit, null, null, null, BYTE_TYPE);
+                return new Cast(definition.byteType, definition.byteType, explicit, null, null, null, definition.byteType);
             } else if (expected.clazz == Short.class && internal) {
-                return new Cast(BYTE_TYPE, SHORT_TYPE, explicit, null, null, null, SHORT_TYPE);
+                return new Cast(definition.byteType, definition.shortType, explicit, null, null, null, definition.shortType);
             } else if (expected.clazz == Character.class && explicit && internal) {
-                return new Cast(BYTE_TYPE, CHAR_TYPE, true, null, null, null, CHAR_TYPE);
+                return new Cast(definition.byteType, definition.charType, true, null, null, null, definition.charType);
             } else if (expected.clazz == Integer.class && internal) {
-                return new Cast(BYTE_TYPE, INT_TYPE, explicit, null, null, null, INT_TYPE);
+                return new Cast(definition.byteType, definition.intType, explicit, null, null, null, definition.intType);
             } else if (expected.clazz == Long.class && internal) {
-                return new Cast(BYTE_TYPE, LONG_TYPE, explicit, null, null, null, LONG_TYPE);
+                return new Cast(definition.byteType, definition.longType, explicit, null, null, null, definition.longType);
             } else if (expected.clazz == Float.class && internal) {
-                return new Cast(BYTE_TYPE, FLOAT_TYPE, explicit, null, null, null, FLOAT_TYPE);
+                return new Cast(definition.byteType, definition.floatType, explicit, null, null, null, definition.floatType);
             } else if (expected.clazz == Double.class && internal) {
-                return new Cast(BYTE_TYPE, DOUBLE_TYPE, explicit, null, null, null, DOUBLE_TYPE);
+                return new Cast(definition.byteType, definition.doubleType, explicit, null, null, null, definition.doubleType);
             }
         } else if (actual.clazz == short.class) {
             if (expected.dynamic) {
-                return new Cast(SHORT_OBJ_TYPE, DEF_TYPE, explicit, null, null, SHORT_TYPE, null);
+                return new Cast(definition.ShortType, definition.DefType, explicit, null, null, definition.shortType, null);
             } else if (expected.clazz == Object.class && internal) {
-                return new Cast(SHORT_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, SHORT_TYPE, null);
+                return new Cast(definition.ShortType, definition.ObjectType, explicit, null, null, definition.shortType, null);
             } else if (expected.clazz == Number.class && internal) {
-                return new Cast(SHORT_OBJ_TYPE, NUMBER_TYPE, explicit, null, null, SHORT_TYPE, null);
+                return new Cast(definition.ShortType, definition.NumberType, explicit, null, null, definition.shortType, null);
             } else if (expected.clazz == byte.class && explicit) {
-                return new Cast(SHORT_TYPE, BYTE_TYPE, true);
+                return new Cast(definition.shortType, definition.byteType, true);
             } else if (expected.clazz == char.class && explicit) {
-                return new Cast(SHORT_TYPE, CHAR_TYPE, true);
+                return new Cast(definition.shortType, definition.charType, true);
             } else if (expected.clazz == int.class) {
-                return new Cast(SHORT_TYPE, INT_TYPE, explicit);
+                return new Cast(definition.shortType, definition.intType, explicit);
             } else if (expected.clazz == long.class) {
-                return new Cast(SHORT_TYPE, LONG_TYPE, explicit);
+                return new Cast(definition.shortType, definition.longType, explicit);
             } else if (expected.clazz == float.class) {
-                return new Cast(SHORT_TYPE, FLOAT_TYPE, explicit);
+                return new Cast(definition.shortType, definition.floatType, explicit);
             } else if (expected.clazz == double.class) {
-                return new Cast(SHORT_TYPE, DOUBLE_TYPE, explicit);
+                return new Cast(definition.shortType, definition.doubleType, explicit);
             } else if (expected.clazz == Byte.class && explicit && internal) {
-                return new Cast(SHORT_TYPE, BYTE_TYPE, true, null, null, null, BYTE_TYPE);
+                return new Cast(definition.shortType, definition.byteType, true, null, null, null, definition.byteType);
             } else if (expected.clazz == Short.class && internal) {
-                return new Cast(SHORT_TYPE, SHORT_TYPE, explicit, null, null, null, SHORT_TYPE);
+                return new Cast(definition.shortType, definition.shortType, explicit, null, null, null, definition.shortType);
             } else if (expected.clazz == Character.class && explicit && internal) {
-                return new Cast(SHORT_TYPE, CHAR_TYPE, true, null, null, null, CHAR_TYPE);
+                return new Cast(definition.shortType, definition.charType, true, null, null, null, definition.charType);
             } else if (expected.clazz == Integer.class && internal) {
-                return new Cast(SHORT_TYPE, INT_TYPE, explicit, null, null, null, INT_TYPE);
+                return new Cast(definition.shortType, definition.intType, explicit, null, null, null, definition.intType);
             } else if (expected.clazz == Long.class && internal) {
-                return new Cast(SHORT_TYPE, LONG_TYPE, explicit, null, null, null, LONG_TYPE);
+                return new Cast(definition.shortType, definition.longType, explicit, null, null, null, definition.longType);
             } else if (expected.clazz == Float.class && internal) {
-                return new Cast(SHORT_TYPE, FLOAT_TYPE, explicit, null, null, null, FLOAT_TYPE);
+                return new Cast(definition.shortType, definition.floatType, explicit, null, null, null, definition.floatType);
             } else if (expected.clazz == Double.class && internal) {
-                return new Cast(SHORT_TYPE, DOUBLE_TYPE, explicit, null, null, null, DOUBLE_TYPE);
+                return new Cast(definition.shortType, definition.doubleType, explicit, null, null, null, definition.doubleType);
             }
         } else if (actual.clazz == char.class) {
             if (expected.dynamic) {
-                return new Cast(CHAR_OBJ_TYPE, DEF_TYPE, explicit, null, null, CHAR_TYPE, null);
+                return new Cast(definition.CharacterType, definition.DefType, explicit, null, null, definition.charType, null);
             } else if (expected.clazz == Object.class && internal) {
-                return new Cast(CHAR_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, CHAR_TYPE, null);
+                return new Cast(definition.CharacterType, definition.ObjectType, explicit, null, null, definition.charType, null);
             } else if (expected.clazz == Number.class && internal) {
-                return new Cast(CHAR_OBJ_TYPE, NUMBER_TYPE, explicit, null, null, CHAR_TYPE, null);
+                return new Cast(definition.CharacterType, definition.NumberType, explicit, null, null, definition.charType, null);
             } else if (expected.clazz == String.class) {
-                return new Cast(CHAR_TYPE, STRING_TYPE, explicit);
+                return new Cast(definition.charType, definition.StringType, explicit);
             } else if (expected.clazz == byte.class && explicit) {
-                return new Cast(CHAR_TYPE, BYTE_TYPE, true);
+                return new Cast(definition.charType, definition.byteType, true);
             } else if (expected.clazz == short.class && explicit) {
-                return new Cast(CHAR_TYPE, SHORT_TYPE, true);
+                return new Cast(definition.charType, definition.shortType, true);
             } else if (expected.clazz == int.class) {
-                return new Cast(CHAR_TYPE, INT_TYPE, explicit);
+                return new Cast(definition.charType, definition.intType, explicit);
             } else if (expected.clazz == long.class) {
-                return new Cast(CHAR_TYPE, LONG_TYPE, explicit);
+                return new Cast(definition.charType, definition.longType, explicit);
             } else if (expected.clazz == float.class) {
-                return new Cast(CHAR_TYPE, FLOAT_TYPE, explicit);
+                return new Cast(definition.charType, definition.floatType, explicit);
             } else if (expected.clazz == double.class) {
-                return new Cast(CHAR_TYPE, DOUBLE_TYPE, explicit);
+                return new Cast(definition.charType, definition.doubleType, explicit);
             } else if (expected.clazz == Byte.class && explicit && internal) {
-                return new Cast(CHAR_TYPE, BYTE_TYPE, true, null, null, null, BYTE_TYPE);
+                return new Cast(definition.charType, definition.byteType, true, null, null, null, definition.byteType);
             } else if (expected.clazz == Short.class && internal) {
-                return new Cast(CHAR_TYPE, SHORT_TYPE, explicit, null, null, null, SHORT_TYPE);
+                return new Cast(definition.charType, definition.shortType, explicit, null, null, null, definition.shortType);
             } else if (expected.clazz == Character.class && internal) {
-                return new Cast(CHAR_TYPE, CHAR_TYPE, true, null, null, null, CHAR_TYPE);
+                return new Cast(definition.charType, definition.charType, true, null, null, null, definition.charType);
             } else if (expected.clazz == Integer.class && internal) {
-                return new Cast(CHAR_TYPE, INT_TYPE, explicit, null, null, null, INT_TYPE);
+                return new Cast(definition.charType, definition.intType, explicit, null, null, null, definition.intType);
             } else if (expected.clazz == Long.class && internal) {
-                return new Cast(CHAR_TYPE, LONG_TYPE, explicit, null, null, null, LONG_TYPE);
+                return new Cast(definition.charType, definition.longType, explicit, null, null, null, definition.longType);
             } else if (expected.clazz == Float.class && internal) {
-                return new Cast(CHAR_TYPE, FLOAT_TYPE, explicit, null, null, null, FLOAT_TYPE);
+                return new Cast(definition.charType, definition.floatType, explicit, null, null, null, definition.floatType);
             } else if (expected.clazz == Double.class && internal) {
-                return new Cast(CHAR_TYPE, DOUBLE_TYPE, explicit, null, null, null, DOUBLE_TYPE);
+                return new Cast(definition.charType, definition.doubleType, explicit, null, null, null, definition.doubleType);
             }
         } else if (actual.clazz == int.class) {
             if (expected.dynamic) {
-                return new Cast(INT_OBJ_TYPE, DEF_TYPE, explicit, null, null, INT_TYPE, null);
+                return new Cast(definition.IntegerType, definition.DefType, explicit, null, null, definition.intType, null);
             } else if (expected.clazz == Object.class && internal) {
-                return new Cast(INT_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, INT_TYPE, null);
+                return new Cast(definition.IntegerType, definition.ObjectType, explicit, null, null, definition.intType, null);
             } else if (expected.clazz == Number.class && internal) {
-                return new Cast(INT_OBJ_TYPE, NUMBER_TYPE, explicit, null, null, INT_TYPE, null);
+                return new Cast(definition.IntegerType, definition.NumberType, explicit, null, null, definition.intType, null);
             } else if (expected.clazz == byte.class && explicit) {
-                return new Cast(INT_TYPE, BYTE_TYPE, true);
+                return new Cast(definition.intType, definition.byteType, true);
             } else if (expected.clazz == char.class && explicit) {
-                return new Cast(INT_TYPE, CHAR_TYPE, true);
+                return new Cast(definition.intType, definition.charType, true);
             } else if (expected.clazz == short.class && explicit) {
-                return new Cast(INT_TYPE, SHORT_TYPE, true);
+                return new Cast(definition.intType, definition.shortType, true);
             } else if (expected.clazz == long.class) {
-                return new Cast(INT_TYPE, LONG_TYPE, explicit);
+                return new Cast(definition.intType, definition.longType, explicit);
             } else if (expected.clazz == float.class) {
-                return new Cast(INT_TYPE, FLOAT_TYPE, explicit);
+                return new Cast(definition.intType, definition.floatType, explicit);
             } else if (expected.clazz == double.class) {
-                return new Cast(INT_TYPE, DOUBLE_TYPE, explicit);
+                return new Cast(definition.intType, definition.doubleType, explicit);
             } else if (expected.clazz == Byte.class && explicit && internal) {
-                return new Cast(INT_TYPE, BYTE_TYPE, true, null, null, null, BYTE_TYPE);
+                return new Cast(definition.intType, definition.byteType, true, null, null, null, definition.byteType);
             } else if (expected.clazz == Short.class && explicit && internal) {
-                return new Cast(INT_TYPE, SHORT_TYPE, true, null, null, null, SHORT_TYPE);
+                return new Cast(definition.intType, definition.shortType, true, null, null, null, definition.shortType);
             } else if (expected.clazz == Character.class && explicit && internal) {
-                return new Cast(INT_TYPE, CHAR_TYPE, true, null, null, null, CHAR_TYPE);
+                return new Cast(definition.intType, definition.charType, true, null, null, null, definition.charType);
             } else if (expected.clazz == Integer.class && internal) {
-                return new Cast(INT_TYPE, INT_TYPE, explicit, null, null, null, INT_TYPE);
+                return new Cast(definition.intType, definition.intType, explicit, null, null, null, definition.intType);
             } else if (expected.clazz == Long.class && internal) {
-                return new Cast(INT_TYPE, LONG_TYPE, explicit, null, null, null, LONG_TYPE);
+                return new Cast(definition.intType, definition.longType, explicit, null, null, null, definition.longType);
             } else if (expected.clazz == Float.class && internal) {
-                return new Cast(INT_TYPE, FLOAT_TYPE, explicit, null, null, null, FLOAT_TYPE);
+                return new Cast(definition.intType, definition.floatType, explicit, null, null, null, definition.floatType);
             } else if (expected.clazz == Double.class && internal) {
-                return new Cast(INT_TYPE, DOUBLE_TYPE, explicit, null, null, null, DOUBLE_TYPE);
+                return new Cast(definition.intType, definition.doubleType, explicit, null, null, null, definition.doubleType);
             }
         } else if (actual.clazz == long.class) {
             if (expected.dynamic) {
-                return new Cast(LONG_OBJ_TYPE, DEF_TYPE, explicit, null, null, LONG_TYPE, null);
+                return new Cast(definition.LongType, definition.DefType, explicit, null, null, definition.longType, null);
             } else if (expected.clazz == Object.class && internal) {
-                return new Cast(LONG_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, LONG_TYPE, null);
+                return new Cast(definition.LongType, definition.ObjectType, explicit, null, null, definition.longType, null);
             } else if (expected.clazz == Number.class && internal) {
-                return new Cast(LONG_OBJ_TYPE, NUMBER_TYPE, explicit, null, null, LONG_TYPE, null);
+                return new Cast(definition.LongType, definition.NumberType, explicit, null, null, definition.longType, null);
             } else if (expected.clazz == byte.class && explicit) {
-                return new Cast(LONG_TYPE, BYTE_TYPE, true);
+                return new Cast(definition.longType, definition.byteType, true);
             } else if (expected.clazz == char.class && explicit) {
-                return new Cast(LONG_TYPE, CHAR_TYPE, true);
+                return new Cast(definition.longType, definition.charType, true);
             } else if (expected.clazz == short.class && explicit) {
-                return new Cast(LONG_TYPE, SHORT_TYPE, true);
+                return new Cast(definition.longType, definition.shortType, true);
             } else if (expected.clazz == int.class && explicit) {
-                return new Cast(LONG_TYPE, INT_TYPE, true);
+                return new Cast(definition.longType, definition.intType, true);
             } else if (expected.clazz == float.class) {
-                return new Cast(LONG_TYPE, FLOAT_TYPE, explicit);
+                return new Cast(definition.longType, definition.floatType, explicit);
             } else if (expected.clazz == double.class) {
-                return new Cast(LONG_TYPE, DOUBLE_TYPE, explicit);
+                return new Cast(definition.longType, definition.doubleType, explicit);
             } else if (expected.clazz == Byte.class && explicit && internal) {
-                return new Cast(LONG_TYPE, BYTE_TYPE, true, null, null, null, BYTE_TYPE);
+                return new Cast(definition.longType, definition.byteType, true, null, null, null, definition.byteType);
             } else if (expected.clazz == Short.class && explicit && internal) {
-                return new Cast(LONG_TYPE, SHORT_TYPE, true, null, null, null, SHORT_TYPE);
+                return new Cast(definition.longType, definition.shortType, true, null, null, null, definition.shortType);
             } else if (expected.clazz == Character.class && explicit && internal) {
-                return new Cast(LONG_TYPE, CHAR_TYPE, true, null, null, null, CHAR_TYPE);
+                return new Cast(definition.longType, definition.charType, true, null, null, null, definition.charType);
             } else if (expected.clazz == Integer.class && explicit && internal) {
-                return new Cast(LONG_TYPE, INT_TYPE, true, null, null, null, INT_TYPE);
+                return new Cast(definition.longType, definition.intType, true, null, null, null, definition.intType);
             } else if (expected.clazz == Long.class && internal) {
-                return new Cast(LONG_TYPE, LONG_TYPE, explicit, null, null, null, LONG_TYPE);
+                return new Cast(definition.longType, definition.longType, explicit, null, null, null, definition.longType);
             } else if (expected.clazz == Float.class && internal) {
-                return new Cast(LONG_TYPE, FLOAT_TYPE, explicit, null, null, null, FLOAT_TYPE);
+                return new Cast(definition.longType, definition.floatType, explicit, null, null, null, definition.floatType);
             } else if (expected.clazz == Double.class && internal) {
-                return new Cast(LONG_TYPE, DOUBLE_TYPE, explicit, null, null, null, DOUBLE_TYPE);
+                return new Cast(definition.longType, definition.doubleType, explicit, null, null, null, definition.doubleType);
             }
         } else if (actual.clazz == float.class) {
             if (expected.dynamic) {
-                return new Cast(FLOAT_OBJ_TYPE, DEF_TYPE, explicit, null, null, FLOAT_TYPE, null);
+                return new Cast(definition.FloatType, definition.DefType, explicit, null, null, definition.floatType, null);
             } else if (expected.clazz == Object.class && internal) {
-                return new Cast(FLOAT_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, FLOAT_TYPE, null);
+                return new Cast(definition.FloatType, definition.ObjectType, explicit, null, null, definition.floatType, null);
             } else if (expected.clazz == Number.class && internal) {
-                return new Cast(FLOAT_OBJ_TYPE, NUMBER_TYPE, explicit, null, null, FLOAT_TYPE, null);
+                return new Cast(definition.FloatType, definition.NumberType, explicit, null, null, definition.floatType, null);
             } else if (expected.clazz == byte.class && explicit) {
-                return new Cast(FLOAT_TYPE, BYTE_TYPE, true);
+                return new Cast(definition.floatType, definition.byteType, true);
             } else if (expected.clazz == char.class && explicit) {
-                return new Cast(FLOAT_TYPE, CHAR_TYPE, true);
+                return new Cast(definition.floatType, definition.charType, true);
             } else if (expected.clazz == short.class && explicit) {
-                return new Cast(FLOAT_TYPE, SHORT_TYPE, true);
+                return new Cast(definition.floatType, definition.shortType, true);
             } else if (expected.clazz == int.class && explicit) {
-                return new Cast(FLOAT_TYPE, INT_TYPE, true);
+                return new Cast(definition.floatType, definition.intType, true);
             } else if (expected.clazz == long.class && explicit) {
-                return new Cast(FLOAT_TYPE, LONG_TYPE, true);
+                return new Cast(definition.floatType, definition.longType, true);
             } else if (expected.clazz == double.class) {
-                return new Cast(FLOAT_TYPE, DOUBLE_TYPE, explicit);
+                return new Cast(definition.floatType, definition.doubleType, explicit);
             } else if (expected.clazz == Byte.class && explicit && internal) {
-                return new Cast(FLOAT_TYPE, BYTE_TYPE, true, null, null, null, BYTE_TYPE);
+                return new Cast(definition.floatType, definition.byteType, true, null, null, null, definition.byteType);
             } else if (expected.clazz == Short.class && explicit && internal) {
-                return new Cast(FLOAT_TYPE, SHORT_TYPE, true, null, null, null, SHORT_TYPE);
+                return new Cast(definition.floatType, definition.shortType, true, null, null, null, definition.shortType);
             } else if (expected.clazz == Character.class && explicit && internal) {
-                return new Cast(FLOAT_TYPE, CHAR_TYPE, true, null, null, null, CHAR_TYPE);
+                return new Cast(definition.floatType, definition.charType, true, null, null, null, definition.charType);
             } else if (expected.clazz == Integer.class && explicit && internal) {
-                return new Cast(FLOAT_TYPE, INT_TYPE, true, null, null, null, INT_TYPE);
+                return new Cast(definition.floatType, definition.intType, true, null, null, null, definition.intType);
             } else if (expected.clazz == Long.class && explicit && internal) {
-                return new Cast(FLOAT_TYPE, LONG_TYPE, true, null, null, null, LONG_TYPE);
+                return new Cast(definition.floatType, definition.longType, true, null, null, null, definition.longType);
             } else if (expected.clazz == Float.class && internal) {
-                return new Cast(FLOAT_TYPE, FLOAT_TYPE, explicit, null, null, null, FLOAT_TYPE);
+                return new Cast(definition.floatType, definition.floatType, explicit, null, null, null, definition.floatType);
             } else if (expected.clazz == Double.class && internal) {
-                return new Cast(FLOAT_TYPE, DOUBLE_TYPE, explicit, null, null, null, DOUBLE_TYPE);
+                return new Cast(definition.floatType, definition.doubleType, explicit, null, null, null, definition.doubleType);
             }
         } else if (actual.clazz == double.class) {
             if (expected.dynamic) {
-                return new Cast(DOUBLE_OBJ_TYPE, DEF_TYPE, explicit, null, null, DOUBLE_TYPE, null);
+                return new Cast(definition.DoubleType, definition.DefType, explicit, null, null, definition.doubleType, null);
             } else if (expected.clazz == Object.class && internal) {
-                return new Cast(DOUBLE_OBJ_TYPE, OBJECT_TYPE, explicit, null, null, DOUBLE_TYPE, null);
+                return new Cast(definition.DoubleType, definition.ObjectType, explicit, null, null, definition.doubleType, null);
             } else if (expected.clazz == Number.class && internal) {
-                return new Cast(DOUBLE_OBJ_TYPE, NUMBER_TYPE, explicit, null, null, DOUBLE_TYPE, null);
+                return new Cast(definition.DoubleType, definition.NumberType, explicit, null, null, definition.doubleType, null);
             } else if (expected.clazz == byte.class && explicit) {
-                return new Cast(DOUBLE_TYPE, BYTE_TYPE, true);
+                return new Cast(definition.doubleType, definition.byteType, true);
             } else if (expected.clazz == char.class && explicit) {
-                return new Cast(DOUBLE_TYPE, CHAR_TYPE, true);
+                return new Cast(definition.doubleType, definition.charType, true);
             } else if (expected.clazz == short.class && explicit) {
-                return new Cast(DOUBLE_TYPE, SHORT_TYPE, true);
+                return new Cast(definition.doubleType, definition.shortType, true);
             } else if (expected.clazz == int.class && explicit) {
-                return new Cast(DOUBLE_TYPE, INT_TYPE, true);
+                return new Cast(definition.doubleType, definition.intType, true);
             } else if (expected.clazz == long.class && explicit) {
-                return new Cast(DOUBLE_TYPE, LONG_TYPE, true);
+                return new Cast(definition.doubleType, definition.longType, true);
             } else if (expected.clazz == float.class && explicit) {
-                return new Cast(DOUBLE_TYPE, FLOAT_TYPE, true);
+                return new Cast(definition.doubleType, definition.floatType, true);
             } else if (expected.clazz == Byte.class && explicit && internal) {
-                return new Cast(DOUBLE_TYPE, BYTE_TYPE, true, null, null, null, BYTE_TYPE);
+                return new Cast(definition.doubleType, definition.byteType, true, null, null, null, definition.byteType);
             } else if (expected.clazz == Short.class && explicit && internal) {
-                return new Cast(DOUBLE_TYPE, SHORT_TYPE, true, null, null, null, SHORT_TYPE);
+                return new Cast(definition.doubleType, definition.shortType, true, null, null, null, definition.shortType);
             } else if (expected.clazz == Character.class && explicit && internal) {
-                return new Cast(DOUBLE_TYPE, CHAR_TYPE, true, null, null, null, CHAR_TYPE);
+                return new Cast(definition.doubleType, definition.charType, true, null, null, null, definition.charType);
             } else if (expected.clazz == Integer.class && explicit && internal) {
-                return new Cast(DOUBLE_TYPE, INT_TYPE, true, null, null, null, INT_TYPE);
+                return new Cast(definition.doubleType, definition.intType, true, null, null, null, definition.intType);
             } else if (expected.clazz == Long.class && explicit && internal) {
-                return new Cast(DOUBLE_TYPE, LONG_TYPE, true, null, null, null, LONG_TYPE);
+                return new Cast(definition.doubleType, definition.longType, true, null, null, null, definition.longType);
             } else if (expected.clazz == Float.class && explicit && internal) {
-                return new Cast(DOUBLE_TYPE, FLOAT_TYPE, true, null, null, null, FLOAT_TYPE);
+                return new Cast(definition.doubleType, definition.floatType, true, null, null, null, definition.floatType);
             } else if (expected.clazz == Double.class && internal) {
-                return new Cast(DOUBLE_TYPE, DOUBLE_TYPE, explicit, null, null, null, DOUBLE_TYPE);
+                return new Cast(definition.doubleType, definition.doubleType, explicit, null, null, null, definition.doubleType);
             }
         } else if (actual.clazz == Boolean.class) {
             if (expected.clazz == boolean.class && internal) {
-                return new Cast(BOOLEAN_TYPE, BOOLEAN_TYPE, explicit, BOOLEAN_TYPE, null, null, null);
+                return new Cast(definition.booleanType, definition.booleanType, explicit, definition.booleanType, null, null, null);
             }
         } else if (actual.clazz == Byte.class) {
             if (expected.clazz == byte.class && internal) {
-                return new Cast(BYTE_TYPE, BYTE_TYPE, explicit, BYTE_TYPE, null, null, null);
+                return new Cast(definition.byteType, definition.byteType, explicit, definition.byteType, null, null, null);
             } else if (expected.clazz == short.class && internal) {
-                return new Cast(BYTE_TYPE, SHORT_TYPE, explicit, BYTE_TYPE, null, null, null);
+                return new Cast(definition.byteType, definition.shortType, explicit, definition.byteType, null, null, null);
             } else if (expected.clazz == char.class && explicit && internal) {
-                return new Cast(BYTE_TYPE, CHAR_TYPE, true, BYTE_TYPE, null, null, null);
+                return new Cast(definition.byteType, definition.charType, true, definition.byteType, null, null, null);
             } else if (expected.clazz == int.class && internal) {
-                return new Cast(BYTE_TYPE, INT_TYPE, explicit, BYTE_TYPE, null, null, null);
+                return new Cast(definition.byteType, definition.intType, explicit, definition.byteType, null, null, null);
             } else if (expected.clazz == long.class && internal) {
-                return new Cast(BYTE_TYPE, LONG_TYPE, explicit, BYTE_TYPE, null, null, null);
+                return new Cast(definition.byteType, definition.longType, explicit, definition.byteType, null, null, null);
             } else if (expected.clazz == float.class && internal) {
-                return new Cast(BYTE_TYPE, FLOAT_TYPE, explicit, BYTE_TYPE, null, null, null);
+                return new Cast(definition.byteType, definition.floatType, explicit, definition.byteType, null, null, null);
             } else if (expected.clazz == double.class && internal) {
-                return new Cast(BYTE_TYPE, DOUBLE_TYPE, explicit, BYTE_TYPE, null, null, null);
+                return new Cast(definition.byteType, definition.doubleType, explicit, definition.byteType, null, null, null);
             }
         } else if (actual.clazz == Short.class) {
             if (expected.clazz == byte.class && explicit && internal) {
-                return new Cast(SHORT_TYPE, BYTE_TYPE, true, SHORT_TYPE, null, null, null);
+                return new Cast(definition.shortType, definition.byteType, true, definition.shortType, null, null, null);
             } else if (expected.clazz == short.class && internal) {
-                return new Cast(SHORT_TYPE, SHORT_TYPE, explicit, SHORT_TYPE, null, null, null);
+                return new Cast(definition.shortType, definition.shortType, explicit, definition.shortType, null, null, null);
             } else if (expected.clazz == char.class && explicit && internal) {
-                return new Cast(SHORT_TYPE, CHAR_TYPE, true, SHORT_TYPE, null, null, null);
+                return new Cast(definition.shortType, definition.charType, true, definition.shortType, null, null, null);
             } else if (expected.clazz == int.class && internal) {
-                return new Cast(SHORT_TYPE, INT_TYPE, explicit, SHORT_TYPE, null, null, null);
+                return new Cast(definition.shortType, definition.intType, explicit, definition.shortType, null, null, null);
             } else if (expected.clazz == long.class && internal) {
-                return new Cast(SHORT_TYPE, LONG_TYPE, explicit, SHORT_TYPE, null, null, null);
+                return new Cast(definition.shortType, definition.longType, explicit, definition.shortType, null, null, null);
             } else if (expected.clazz == float.class && internal) {
-                return new Cast(SHORT_TYPE, FLOAT_TYPE, explicit, SHORT_TYPE, null, null, null);
+                return new Cast(definition.shortType, definition.floatType, explicit, definition.shortType, null, null, null);
             } else if (expected.clazz == double.class && internal) {
-                return new Cast(SHORT_TYPE, DOUBLE_TYPE, explicit, SHORT_TYPE, null, null, null);
+                return new Cast(definition.shortType, definition.doubleType, explicit, definition.shortType, null, null, null);
             }
         } else if (actual.clazz == Character.class) {
             if (expected.clazz == byte.class && explicit && internal) {
-                return new Cast(CHAR_TYPE, BYTE_TYPE, true, CHAR_TYPE, null, null, null);
+                return new Cast(definition.charType, definition.byteType, true, definition.charType, null, null, null);
             } else if (expected.clazz == short.class && explicit && internal) {
-                return new Cast(CHAR_TYPE, SHORT_TYPE, true, CHAR_TYPE, null, null, null);
+                return new Cast(definition.charType, definition.shortType, true, definition.charType, null, null, null);
             } else if (expected.clazz == char.class && internal) {
-                return new Cast(CHAR_TYPE, CHAR_TYPE, explicit, CHAR_TYPE, null, null, null);
+                return new Cast(definition.charType, definition.charType, explicit, definition.charType, null, null, null);
             } else if (expected.clazz == int.class && internal) {
-                return new Cast(CHAR_TYPE, INT_TYPE, explicit, CHAR_TYPE, null, null, null);
+                return new Cast(definition.charType, definition.intType, explicit, definition.charType, null, null, null);
             } else if (expected.clazz == long.class && internal) {
-                return new Cast(CHAR_TYPE, LONG_TYPE, explicit, CHAR_TYPE, null, null, null);
+                return new Cast(definition.charType, definition.longType, explicit, definition.charType, null, null, null);
             } else if (expected.clazz == float.class && internal) {
-                return new Cast(CHAR_TYPE, FLOAT_TYPE, explicit, CHAR_TYPE, null, null, null);
+                return new Cast(definition.charType, definition.floatType, explicit, definition.charType, null, null, null);
             } else if (expected.clazz == double.class && internal) {
-                return new Cast(CHAR_TYPE, DOUBLE_TYPE, explicit, CHAR_TYPE, null, null, null);
+                return new Cast(definition.charType, definition.doubleType, explicit, definition.charType, null, null, null);
             }
         } else if (actual.clazz == Integer.class) {
             if (expected.clazz == byte.class && explicit && internal) {
-                return new Cast(INT_TYPE, BYTE_TYPE, true, INT_TYPE, null, null, null);
+                return new Cast(definition.intType, definition.byteType, true, definition.intType, null, null, null);
             } else if (expected.clazz == short.class && explicit && internal) {
-                return new Cast(INT_TYPE, SHORT_TYPE, true, INT_TYPE, null, null, null);
+                return new Cast(definition.intType, definition.shortType, true, definition.intType, null, null, null);
             } else if (expected.clazz == char.class && explicit && internal) {
-                return new Cast(INT_TYPE, CHAR_TYPE, true, INT_TYPE, null, null, null);
+                return new Cast(definition.intType, definition.charType, true, definition.intType, null, null, null);
             } else if (expected.clazz == int.class && internal) {
-                return new Cast(INT_TYPE, INT_TYPE, explicit, INT_TYPE, null, null, null);
+                return new Cast(definition.intType, definition.intType, explicit, definition.intType, null, null, null);
             } else if (expected.clazz == long.class && internal) {
-                return new Cast(INT_TYPE, LONG_TYPE, explicit, INT_TYPE, null, null, null);
+                return new Cast(definition.intType, definition.longType, explicit, definition.intType, null, null, null);
             } else if (expected.clazz == float.class && internal) {
-                return new Cast(INT_TYPE, FLOAT_TYPE, explicit, INT_TYPE, null, null, null);
+                return new Cast(definition.intType, definition.floatType, explicit, definition.intType, null, null, null);
             } else if (expected.clazz == double.class && internal) {
-                return new Cast(INT_TYPE, DOUBLE_TYPE, explicit, INT_TYPE, null, null, null);
+                return new Cast(definition.intType, definition.doubleType, explicit, definition.intType, null, null, null);
             }
         } else if (actual.clazz == Long.class) {
             if (expected.clazz == byte.class && explicit && internal) {
-                return new Cast(LONG_TYPE, BYTE_TYPE, true, LONG_TYPE, null, null, null);
+                return new Cast(definition.longType, definition.byteType, true, definition.longType, null, null, null);
             } else if (expected.clazz == short.class && explicit && internal) {
-                return new Cast(LONG_TYPE, SHORT_TYPE, true, LONG_TYPE, null, null, null);
+                return new Cast(definition.longType, definition.shortType, true, definition.longType, null, null, null);
             } else if (expected.clazz == char.class && explicit && internal) {
-                return new Cast(LONG_TYPE, CHAR_TYPE, true, LONG_TYPE, null, null, null);
+                return new Cast(definition.longType, definition.charType, true, definition.longType, null, null, null);
             } else if (expected.clazz == int.class && explicit && internal) {
-                return new Cast(LONG_TYPE, INT_TYPE, true, LONG_TYPE, null, null, null);
+                return new Cast(definition.longType, definition.intType, true, definition.longType, null, null, null);
             } else if (expected.clazz == long.class && internal) {
-                return new Cast(LONG_TYPE, LONG_TYPE, explicit, LONG_TYPE, null, null, null);
+                return new Cast(definition.longType, definition.longType, explicit, definition.longType, null, null, null);
             } else if (expected.clazz == float.class && internal) {
-                return new Cast(LONG_TYPE, FLOAT_TYPE, explicit, LONG_TYPE, null, null, null);
+                return new Cast(definition.longType, definition.floatType, explicit, definition.longType, null, null, null);
             } else if (expected.clazz == double.class && internal) {
-                return new Cast(LONG_TYPE, DOUBLE_TYPE, explicit, LONG_TYPE, null, null, null);
+                return new Cast(definition.longType, definition.doubleType, explicit, definition.longType, null, null, null);
             }
         } else if (actual.clazz == Float.class) {
             if (expected.clazz == byte.class && explicit && internal) {
-                return new Cast(FLOAT_TYPE, BYTE_TYPE, true, FLOAT_TYPE, null, null, null);
+                return new Cast(definition.floatType, definition.byteType, true, definition.floatType, null, null, null);
             } else if (expected.clazz == short.class && explicit && internal) {
-                return new Cast(FLOAT_TYPE, SHORT_TYPE, true, FLOAT_TYPE, null, null, null);
+                return new Cast(definition.floatType, definition.shortType, true, definition.floatType, null, null, null);
             } else if (expected.clazz == char.class && explicit && internal) {
-                return new Cast(FLOAT_TYPE, CHAR_TYPE, true, FLOAT_TYPE, null, null, null);
+                return new Cast(definition.floatType, definition.charType, true, definition.floatType, null, null, null);
             } else if (expected.clazz == int.class && explicit && internal) {
-                return new Cast(FLOAT_TYPE, INT_TYPE, true, FLOAT_TYPE, null, null, null);
+                return new Cast(definition.floatType, definition.intType, true, definition.floatType, null, null, null);
             } else if (expected.clazz == long.class && explicit && internal) {
-                return new Cast(FLOAT_TYPE, LONG_TYPE, true, FLOAT_TYPE, null, null, null);
+                return new Cast(definition.floatType, definition.longType, true, definition.floatType, null, null, null);
             } else if (expected.clazz == float.class && internal) {
-                return new Cast(FLOAT_TYPE, FLOAT_TYPE, explicit, FLOAT_TYPE, null, null, null);
+                return new Cast(definition.floatType, definition.floatType, explicit, definition.floatType, null, null, null);
             } else if (expected.clazz == double.class && internal) {
-                return new Cast(FLOAT_TYPE, DOUBLE_TYPE, explicit, FLOAT_TYPE, null, null, null);
+                return new Cast(definition.floatType, definition.doubleType, explicit, definition.floatType, null, null, null);
             }
         } else if (actual.clazz == Double.class) {
             if (expected.clazz == byte.class && explicit && internal) {
-                return new Cast(DOUBLE_TYPE, BYTE_TYPE, true, DOUBLE_TYPE, null, null, null);
+                return new Cast(definition.doubleType, definition.byteType, true, definition.doubleType, null, null, null);
             } else if (expected.clazz == short.class && explicit && internal) {
-                return new Cast(DOUBLE_TYPE, SHORT_TYPE, true, DOUBLE_TYPE, null, null, null);
+                return new Cast(definition.doubleType, definition.shortType, true, definition.doubleType, null, null, null);
             } else if (expected.clazz == char.class && explicit && internal) {
-                return new Cast(DOUBLE_TYPE, CHAR_TYPE, true, DOUBLE_TYPE, null, null, null);
+                return new Cast(definition.doubleType, definition.charType, true, definition.doubleType, null, null, null);
             } else if (expected.clazz == int.class && explicit && internal) {
-                return new Cast(DOUBLE_TYPE, INT_TYPE, true, DOUBLE_TYPE, null, null, null);
+                return new Cast(definition.doubleType, definition.intType, true, definition.doubleType, null, null, null);
             } else if (expected.clazz == long.class && explicit && internal) {
-                return new Cast(DOUBLE_TYPE, LONG_TYPE, true, DOUBLE_TYPE, null, null, null);
+                return new Cast(definition.doubleType, definition.longType, true, definition.doubleType, null, null, null);
             } else if (expected.clazz == float.class && explicit && internal) {
-                return new Cast(DOUBLE_TYPE, FLOAT_TYPE, true, DOUBLE_TYPE, null, null, null);
+                return new Cast(definition.doubleType, definition.floatType, true, definition.doubleType, null, null, null);
             } else if (expected.clazz == double.class && internal) {
-                return new Cast(DOUBLE_TYPE, DOUBLE_TYPE, explicit, DOUBLE_TYPE, null, null, null);
+                return new Cast(definition.doubleType, definition.doubleType, explicit, definition.doubleType, null, null, null);
             }
         }
 
@@ -489,7 +474,7 @@ public final class AnalyzerCaster {
         }
     }
 
-    public static Object constCast(Location location, final Object constant, final Cast cast) {
+    public Object constCast(Location location, final Object constant, final Cast cast) {
         Class<?> fsort = cast.from.clazz;
         Class<?> tsort = cast.to.clazz;
 
@@ -525,98 +510,98 @@ public final class AnalyzerCaster {
         }
     }
 
-    public static Type promoteNumeric(Type from, boolean decimal) {
+    public Type promoteNumeric(Type from, boolean decimal) {
         Class<?> sort = from.clazz;
 
         if (from.dynamic) {
-            return DEF_TYPE;
+            return definition.DefType;
         } else if ((sort == double.class) && decimal) {
-            return DOUBLE_TYPE;
+            return definition.doubleType;
         } else if ((sort == float.class) && decimal) {
-            return  FLOAT_TYPE;
+            return  definition.floatType;
         } else if (sort == long.class) {
-            return LONG_TYPE;
+            return definition.longType;
         } else if (sort == int.class || sort == char.class || sort == short.class || sort == byte.class) {
-            return INT_TYPE;
+            return definition.intType;
         }
 
         return null;
     }
 
-    public static Type promoteNumeric(Type from0, Type from1, boolean decimal) {
+    public Type promoteNumeric(Type from0, Type from1, boolean decimal) {
         Class<?> sort0 = from0.clazz;
         Class<?> sort1 = from1.clazz;
 
         if (from0.dynamic || from1.dynamic) {
-            return DEF_TYPE;
+            return definition.DefType;
         }
 
         if (decimal) {
             if (sort0 == double.class || sort1 == double.class) {
-                return DOUBLE_TYPE;
+                return definition.doubleType;
             } else if (sort0 == float.class || sort1 == float.class) {
-                return FLOAT_TYPE;
+                return definition.floatType;
             }
         }
 
         if (sort0 == long.class || sort1 == long.class) {
-            return LONG_TYPE;
+            return definition.longType;
         } else if (sort0 == int.class   || sort1 == int.class   ||
                    sort0 == char.class  || sort1 == char.class  ||
                    sort0 == short.class || sort1 == short.class ||
                    sort0 == byte.class  || sort1 == byte.class) {
-            return INT_TYPE;
+            return definition.intType;
         }
 
         return null;
     }
 
-    public static Type promoteAdd(Type from0, Type from1) {
+    public Type promoteAdd(Type from0, Type from1) {
         Class<?> sort0 = from0.clazz;
         Class<?> sort1 = from1.clazz;
 
         if (sort0 == String.class || sort1 == String.class) {
-            return STRING_TYPE;
+            return definition.StringType;
         }
 
         return promoteNumeric(from0, from1, true);
     }
 
-    public static Type promoteXor(Type from0, Type from1) {
+    public Type promoteXor(Type from0, Type from1) {
         Class<?> sort0 = from0.clazz;
         Class<?> sort1 = from1.clazz;
 
         if (from0.dynamic || from1.dynamic) {
-            return DEF_TYPE;
+            return definition.DefType;
         }
 
         if (sort0 == boolean.class || sort1 == boolean.class) {
-            return BOOLEAN_TYPE;
+            return definition.booleanType;
         }
 
         return promoteNumeric(from0, from1, false);
     }
 
-    public static Type promoteEquality(Type from0, Type from1) {
+    public Type promoteEquality(Type from0, Type from1) {
         Class<?> sort0 = from0.clazz;
         Class<?> sort1 = from1.clazz;
 
         if (from0.dynamic || from1.dynamic) {
-            return DEF_TYPE;
+            return definition.DefType;
         }
 
         if (sort0.isPrimitive() && sort1.isPrimitive()) {
             if (sort0 == boolean.class && sort1 == boolean.class) {
-                return BOOLEAN_TYPE;
+                return definition.booleanType;
             }
 
             return promoteNumeric(from0, from1, true);
         }
 
-        return OBJECT_TYPE;
+        return definition.ObjectType;
     }
 
-    public static Type promoteConditional(Type from0, Type from1, Object const0, Object const1) {
+    public Type promoteConditional(Type from0, Type from1, Object const0, Object const1) {
         if (from0.equals(from1)) {
             return from0;
         }
@@ -625,46 +610,46 @@ public final class AnalyzerCaster {
         Class<?> sort1 = from1.clazz;
 
         if (from0.dynamic || from1.dynamic) {
-            return DEF_TYPE;
+            return definition.DefType;
         }
 
         if (sort0.isPrimitive() && sort1.isPrimitive()) {
             if (sort0 == boolean.class && sort1 == boolean.class) {
-                return BOOLEAN_TYPE;
+                return definition.booleanType;
             }
 
             if (sort0 == double.class || sort1 == double.class) {
-                return DOUBLE_TYPE;
+                return definition.doubleType;
             } else if (sort0 == float.class || sort1 == float.class) {
-                return FLOAT_TYPE;
+                return definition.floatType;
             } else if (sort0 == long.class || sort1 == long.class) {
-                return LONG_TYPE;
+                return definition.longType;
             } else {
                 if (sort0 == byte.class) {
                     if (sort1 == byte.class) {
-                        return BYTE_TYPE;
+                        return definition.byteType;
                     } else if (sort1 == short.class) {
                         if (const1 != null) {
                             final short constant = (short)const1;
 
                             if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) {
-                                return BYTE_TYPE;
+                                return definition.byteType;
                             }
                         }
 
-                        return SHORT_TYPE;
+                        return definition.shortType;
                     } else if (sort1 == char.class) {
-                        return INT_TYPE;
+                        return definition.intType;
                     } else if (sort1 == int.class) {
                         if (const1 != null) {
                             final int constant = (int)const1;
 
                             if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) {
-                                return BYTE_TYPE;
+                                return definition.byteType;
                             }
                         }
 
-                        return INT_TYPE;
+                        return definition.intType;
                     }
                 } else if (sort0 == short.class) {
                     if (sort1 == byte.class) {
@@ -672,43 +657,43 @@ public final class AnalyzerCaster {
                             final short constant = (short)const0;
 
                             if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) {
-                                return BYTE_TYPE;
+                                return definition.byteType;
                             }
                         }
 
-                        return SHORT_TYPE;
+                        return definition.shortType;
                     } else if (sort1 == short.class) {
-                        return SHORT_TYPE;
+                        return definition.shortType;
                     } else if (sort1 == char.class) {
-                        return INT_TYPE;
+                        return definition.intType;
                     } else if (sort1 == int.class) {
                         if (const1 != null) {
                             final int constant = (int)const1;
 
                             if (constant <= Short.MAX_VALUE && constant >= Short.MIN_VALUE) {
-                                return SHORT_TYPE;
+                                return definition.shortType;
                             }
                         }
 
-                        return INT_TYPE;
+                        return definition.intType;
                     }
                 } else if (sort0 == char.class) {
                     if (sort1 == byte.class) {
-                        return INT_TYPE;
+                        return definition.intType;
                     } else if (sort1 == short.class) {
-                        return INT_TYPE;
+                        return definition.intType;
                     } else if (sort1 == char.class) {
-                        return CHAR_TYPE;
+                        return definition.charType;
                     } else if (sort1 == int.class) {
                         if (const1 != null) {
                             final int constant = (int)const1;
 
                             if (constant <= Character.MAX_VALUE && constant >= Character.MIN_VALUE) {
-                                return BYTE_TYPE;
+                                return definition.byteType;
                             }
                         }
 
-                        return INT_TYPE;
+                        return definition.intType;
                     }
                 } else if (sort0 == int.class) {
                     if (sort1 == byte.class) {
@@ -716,33 +701,33 @@ public final class AnalyzerCaster {
                             final int constant = (int)const0;
 
                             if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) {
-                                return BYTE_TYPE;
+                                return definition.byteType;
                             }
                         }
 
-                        return INT_TYPE;
+                        return definition.intType;
                     } else if (sort1 == short.class) {
                         if (const0 != null) {
                             final int constant = (int)const0;
 
                             if (constant <= Short.MAX_VALUE && constant >= Short.MIN_VALUE) {
-                                return BYTE_TYPE;
+                                return definition.byteType;
                             }
                         }
 
-                        return INT_TYPE;
+                        return definition.intType;
                     } else if (sort1 == char.class) {
                         if (const0 != null) {
                             final int constant = (int)const0;
 
                             if (constant <= Character.MAX_VALUE && constant >= Character.MIN_VALUE) {
-                                return BYTE_TYPE;
+                                return definition.byteType;
                             }
                         }
 
-                        return INT_TYPE;
+                        return definition.intType;
                     } else if (sort1 == int.class) {
-                        return INT_TYPE;
+                        return definition.intType;
                     }
                 }
             }
@@ -752,8 +737,6 @@ public final class AnalyzerCaster {
         // TODO: to calculate the highest upper bound for the two types and return that.
         // TODO: However, for now we just return objectType that may require an extra cast.
 
-        return OBJECT_TYPE;
+        return definition.ObjectType;
     }
-
-    private AnalyzerCaster() {}
 }

+ 84 - 57
modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java

@@ -19,24 +19,19 @@
 
 package org.elasticsearch.painless;
 
-import org.apache.lucene.util.Constants;
 import org.apache.lucene.util.SetOnce;
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
 import java.lang.reflect.Modifier;
-import java.time.LocalDate;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.PrimitiveIterator;
-import java.util.Spliterator;
 import java.util.Stack;
 
 /**
@@ -65,37 +60,37 @@ public final class Definition {
     /**
      * Whitelist that is "built in" to Painless and required by all scripts.
      */
-    public static final Definition BUILTINS = new Definition(
+    public static final Definition DEFINITION = new Definition(
         Collections.singletonList(WhitelistLoader.loadFromResourceFiles(Definition.class, DEFINITION_FILES)));
 
     /** Some native types as constants: */
-    public static final Type VOID_TYPE = BUILTINS.getType("void");
-    public static final Type BOOLEAN_TYPE = BUILTINS.getType("boolean");
-    public static final Type BOOLEAN_OBJ_TYPE = BUILTINS.getType("Boolean");
-    public static final Type BYTE_TYPE = BUILTINS.getType("byte");
-    public static final Type BYTE_OBJ_TYPE = BUILTINS.getType("Byte");
-    public static final Type SHORT_TYPE = BUILTINS.getType("short");
-    public static final Type SHORT_OBJ_TYPE = BUILTINS.getType("Short");
-    public static final Type INT_TYPE = BUILTINS.getType("int");
-    public static final Type INT_OBJ_TYPE = BUILTINS.getType("Integer");
-    public static final Type LONG_TYPE = BUILTINS.getType("long");
-    public static final Type LONG_OBJ_TYPE = BUILTINS.getType("Long");
-    public static final Type FLOAT_TYPE = BUILTINS.getType("float");
-    public static final Type FLOAT_OBJ_TYPE = BUILTINS.getType("Float");
-    public static final Type DOUBLE_TYPE = BUILTINS.getType("double");
-    public static final Type DOUBLE_OBJ_TYPE = BUILTINS.getType("Double");
-    public static final Type CHAR_TYPE = BUILTINS.getType("char");
-    public static final Type CHAR_OBJ_TYPE = BUILTINS.getType("Character");
-    public static final Type OBJECT_TYPE = BUILTINS.getType("Object");
-    public static final Type DEF_TYPE = BUILTINS.getType("def");
-    public static final Type NUMBER_TYPE = BUILTINS.getType("Number");
-    public static final Type STRING_TYPE = BUILTINS.getType("String");
-    public static final Type EXCEPTION_TYPE = BUILTINS.getType("Exception");
-    public static final Type PATTERN_TYPE = BUILTINS.getType("Pattern");
-    public static final Type MATCHER_TYPE = BUILTINS.getType("Matcher");
-    public static final Type ITERATOR_TYPE = BUILTINS.getType("Iterator");
-    public static final Type ARRAY_LIST_TYPE = BUILTINS.getType("ArrayList");
-    public static final Type HASH_MAP_TYPE = BUILTINS.getType("HashMap");
+    public final Type voidType;
+    public final Type booleanType;
+    public final Type BooleanType;
+    public final Type byteType;
+    public final Type ByteType;
+    public final Type shortType;
+    public final Type ShortType;
+    public final Type intType;
+    public final Type IntegerType;
+    public final Type longType;
+    public final Type LongType;
+    public final Type floatType;
+    public final Type FloatType;
+    public final Type doubleType;
+    public final Type DoubleType;
+    public final Type charType;
+    public final Type CharacterType;
+    public final Type ObjectType;
+    public final Type DefType;
+    public final Type NumberType;
+    public final Type StringType;
+    public final Type ExceptionType;
+    public final Type PatternType;
+    public final Type MatcherType;
+    public final Type IteratorType;
+    public final Type ArrayListType;
+    public final Type HashMapType;
 
     public static final class Type {
         public final String name;
@@ -438,58 +433,58 @@ public final class Definition {
 
     /** Returns whether or not a non-array type exists. */
     public boolean isSimpleType(final String name) {
-        return BUILTINS.structsMap.containsKey(name);
+        return structsMap.containsKey(name);
     }
 
     /** Gets the type given by its name */
     public Type getType(final String name) {
-        return BUILTINS.getTypeInternal(name);
+        return getTypeInternal(name);
     }
 
     /** Creates an array type from the given Struct. */
     public Type getType(final Struct struct, final int dimensions) {
-        return BUILTINS.getTypeInternal(struct, dimensions);
+        return getTypeInternal(struct, dimensions);
     }
 
-    public static Type getBoxedType(Type unboxed) {
+    public Type getBoxedType(Type unboxed) {
         if (unboxed.clazz == boolean.class) {
-            return BOOLEAN_OBJ_TYPE;
+            return BooleanType;
         } else if (unboxed.clazz == byte.class) {
-            return BYTE_OBJ_TYPE;
+            return ByteType;
         } else if (unboxed.clazz == short.class) {
-            return SHORT_OBJ_TYPE;
+            return ShortType;
         } else if (unboxed.clazz == char.class) {
-            return CHAR_OBJ_TYPE;
+            return CharacterType;
         } else if (unboxed.clazz == int.class) {
-            return INT_OBJ_TYPE;
+            return IntegerType;
         } else if (unboxed.clazz == long.class) {
-            return LONG_OBJ_TYPE;
+            return LongType;
         } else if (unboxed.clazz == float.class) {
-            return FLOAT_OBJ_TYPE;
+            return FloatType;
         } else if (unboxed.clazz == double.class) {
-            return DOUBLE_OBJ_TYPE;
+            return DoubleType;
         }
 
         return unboxed;
     }
 
-    public static Type getUnboxedType(Type boxed) {
+    public Type getUnboxedType(Type boxed) {
         if (boxed.clazz == Boolean.class) {
-            return BOOLEAN_TYPE;
+            return booleanType;
         } else if (boxed.clazz == Byte.class) {
-            return BYTE_TYPE;
+            return byteType;
         } else if (boxed.clazz == Short.class) {
-            return SHORT_TYPE;
+            return shortType;
         } else if (boxed.clazz == Character.class) {
-            return CHAR_TYPE;
+            return charType;
         } else if (boxed.clazz == Integer.class) {
-            return INT_TYPE;
+            return intType;
         } else if (boxed.clazz == Long.class) {
-            return LONG_TYPE;
+            return longType;
         } else if (boxed.clazz == Float.class) {
-            return FLOAT_TYPE;
+            return floatType;
         } else if (boxed.clazz == Double.class) {
-            return DOUBLE_TYPE;
+            return doubleType;
         }
 
         return boxed;
@@ -508,12 +503,12 @@ public final class Definition {
     }
 
     public RuntimeClass getRuntimeClass(Class<?> clazz) {
-        return BUILTINS.runtimeMap.get(clazz);
+        return runtimeMap.get(clazz);
     }
 
     /** Collection of all simple types. Used by {@code PainlessDocGenerator} to generate an API reference. */
-    static Collection<Type> allSimpleTypes() {
-        return BUILTINS.simpleTypesMap.values();
+    Collection<Type> allSimpleTypes() {
+        return simpleTypesMap.values();
     }
 
     // INTERNAL IMPLEMENTATION:
@@ -522,6 +517,8 @@ public final class Definition {
     private final Map<String, Struct> structsMap;
     private final Map<String, Type> simpleTypesMap;
 
+    public AnalyzerCaster caster;
+
     private Definition(List<Whitelist> whitelists) {
         structsMap = new HashMap<>();
         simpleTypesMap = new HashMap<>();
@@ -648,6 +645,36 @@ public final class Definition {
         for (final Map.Entry<String,Struct> entry : structsMap.entrySet()) {
             entry.setValue(entry.getValue().freeze());
         }
+
+        voidType = getType("void");
+        booleanType = getType("boolean");
+        BooleanType = getType("Boolean");
+        byteType = getType("byte");
+        ByteType = getType("Byte");
+        shortType = getType("short");
+        ShortType = getType("Short");
+        intType = getType("int");
+        IntegerType = getType("Integer");
+        longType = getType("long");
+        LongType = getType("Long");
+        floatType = getType("float");
+        FloatType = getType("Float");
+        doubleType = getType("double");
+        DoubleType = getType("Double");
+        charType = getType("char");
+        CharacterType = getType("Character");
+        ObjectType = getType("Object");
+        DefType = getType("def");
+        NumberType = getType("Number");
+        StringType = getType("String");
+        ExceptionType = getType("Exception");
+        PatternType = getType("Pattern");
+        MatcherType = getType("Matcher");
+        IteratorType = getType("Iterator");
+        ArrayListType = getType("ArrayList");
+        HashMapType = getType("HashMap");
+
+        caster = new AnalyzerCaster(this);
     }
 
     private void addStruct(ClassLoader whitelistClassLoader, Whitelist.Struct whitelistStruct) {

+ 3 - 3
modules/lang-painless/src/main/java/org/elasticsearch/painless/Locals.java

@@ -72,7 +72,7 @@ public final class Locals {
         }
         // Loop counter to catch infinite loops.  Internal use only.
         if (maxLoopCounter > 0) {
-            locals.defineVariable(null, Definition.INT_TYPE, LOOP, true);
+            locals.defineVariable(null, locals.getDefinition().intType, LOOP, true);
         }
         return locals;
     }
@@ -85,7 +85,7 @@ public final class Locals {
         }
         // Loop counter to catch infinite loops.  Internal use only.
         if (maxLoopCounter > 0) {
-            locals.defineVariable(null, Definition.INT_TYPE, LOOP, true);
+            locals.defineVariable(null, locals.getDefinition().intType, LOOP, true);
         }
         return locals;
     }
@@ -104,7 +104,7 @@ public final class Locals {
 
         // Loop counter to catch infinite loops.  Internal use only.
         if (maxLoopCounter > 0) {
-            locals.defineVariable(null, Definition.INT_TYPE, LOOP, true);
+            locals.defineVariable(null, locals.getDefinition().intType, LOOP, true);
         }
         return locals;
     }

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java

@@ -38,7 +38,7 @@ public final class PainlessPlugin extends Plugin implements ScriptPlugin {
 
     // force to parse our definition at startup (not on the user's first script)
     static {
-        Definition.VOID_TYPE.hashCode();
+        Definition.DEFINITION.hashCode();
     }
 
     @Override

+ 2 - 2
modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngine.java

@@ -101,9 +101,9 @@ public final class PainlessScriptEngine extends AbstractComponent implements Scr
 
         for (ScriptContext<?> context : contexts) {
             if (context.instanceClazz.equals(SearchScript.class) || context.instanceClazz.equals(ExecutableScript.class)) {
-                contextsToCompilers.put(context, new Compiler(GenericElasticsearchScript.class, Definition.BUILTINS));
+                contextsToCompilers.put(context, new Compiler(GenericElasticsearchScript.class, Definition.DEFINITION));
             } else {
-                contextsToCompilers.put(context, new Compiler(context.instanceClazz, Definition.BUILTINS));
+                contextsToCompilers.put(context, new Compiler(context.instanceClazz, Definition.DEFINITION));
             }
         }
 

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java

@@ -191,7 +191,7 @@ public class ScriptClassInfo {
         }
         Definition.Struct struct;
         if (componentType.equals(Object.class)) {
-            struct = Definition.DEF_TYPE.struct;
+            struct = definition.DefType.struct;
         } else {
             Definition.RuntimeClass runtimeClass = definition.getRuntimeClass(componentType);
             if (runtimeClass == null) {

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java

@@ -137,7 +137,7 @@ public final class WriterConstants {
     public static final Method DEF_TO_LONG_EXPLICIT   = getAsmMethod(long.class   , "DefTolongExplicit"  , Object.class);
     public static final Method DEF_TO_FLOAT_EXPLICIT  = getAsmMethod(float.class  , "DefTofloatExplicit" , Object.class);
     public static final Method DEF_TO_DOUBLE_EXPLICIT = getAsmMethod(double.class , "DefTodoubleExplicit", Object.class);
-    public static final Type DEF_ARRAY_LENGTH_METHOD_TYPE = Type.getMethodType(Type.INT_TYPE, Definition.DEF_TYPE.type);
+    public static final Type DEF_ARRAY_LENGTH_METHOD_TYPE = Type.getMethodType(Type.INT_TYPE, Type.getType(Object.class));
 
     /** invokedynamic bootstrap for lambda expression/method references */
     public static final MethodType LAMBDA_BOOTSTRAP_TYPE =

+ 2 - 2
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java

@@ -119,7 +119,7 @@ public abstract class AExpression extends ANode {
      * @return The new child node for the parent node calling this method.
      */
     AExpression cast(Locals locals) {
-        Cast cast = AnalyzerCaster.getLegalCast(location, actual, expected, explicit, internal);
+        Cast cast = locals.getDefinition().caster.getLegalCast(location, actual, expected, explicit, internal);
 
         if (cast == null) {
             if (constant == null || this instanceof EConstant) {
@@ -167,7 +167,7 @@ public abstract class AExpression extends ANode {
                     // from this node because the output data for the EConstant
                     // will already be the same.
 
-                    constant = AnalyzerCaster.constCast(location, constant, cast);
+                    constant = locals.getDefinition().caster.constCast(location, constant, cast);
 
                     EConstant econstant = new EConstant(location, constant);
                     econstant.analyze(locals);

+ 24 - 22
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EAssignment.java

@@ -19,7 +19,6 @@
 
 package org.elasticsearch.painless.node;
 
-import org.elasticsearch.painless.AnalyzerCaster;
 import org.elasticsearch.painless.DefBootstrap;
 import org.elasticsearch.painless.Definition;
 import org.elasticsearch.painless.Definition.Cast;
@@ -51,6 +50,7 @@ public final class EAssignment extends AExpression {
     private Type shiftDistance; // for shifts, the RHS is promoted independently
     private Cast there = null;
     private Cast back = null;
+    private Type DefType = null;
 
     public EAssignment(Location location, AExpression lhs, AExpression rhs, boolean pre, boolean post, Operation operation) {
         super(location);
@@ -80,6 +80,8 @@ public final class EAssignment extends AExpression {
         } else {
             throw new IllegalStateException("Illegal tree structure.");
         }
+
+        DefType = locals.getDefinition().DefType;
     }
 
     private void analyzeLHS(Locals locals) {
@@ -138,33 +140,33 @@ public final class EAssignment extends AExpression {
         boolean shift = false;
 
         if (operation == Operation.MUL) {
-            promote = AnalyzerCaster.promoteNumeric(lhs.actual, rhs.actual, true);
+            promote = locals.getDefinition().caster.promoteNumeric(lhs.actual, rhs.actual, true);
         } else if (operation == Operation.DIV) {
-            promote = AnalyzerCaster.promoteNumeric(lhs.actual, rhs.actual, true);
+            promote = locals.getDefinition().caster.promoteNumeric(lhs.actual, rhs.actual, true);
         } else if (operation == Operation.REM) {
-            promote = AnalyzerCaster.promoteNumeric(lhs.actual, rhs.actual, true);
+            promote = locals.getDefinition().caster.promoteNumeric(lhs.actual, rhs.actual, true);
         } else if (operation == Operation.ADD) {
-            promote = AnalyzerCaster.promoteAdd(lhs.actual, rhs.actual);
+            promote = locals.getDefinition().caster.promoteAdd(lhs.actual, rhs.actual);
         } else if (operation == Operation.SUB) {
-            promote = AnalyzerCaster.promoteNumeric(lhs.actual, rhs.actual, true);
+            promote = locals.getDefinition().caster.promoteNumeric(lhs.actual, rhs.actual, true);
         } else if (operation == Operation.LSH) {
-            promote = AnalyzerCaster.promoteNumeric(lhs.actual, false);
-            shiftDistance = AnalyzerCaster.promoteNumeric(rhs.actual, false);
+            promote = locals.getDefinition().caster.promoteNumeric(lhs.actual, false);
+            shiftDistance = locals.getDefinition().caster.promoteNumeric(rhs.actual, false);
             shift = true;
         } else if (operation == Operation.RSH) {
-            promote = AnalyzerCaster.promoteNumeric(lhs.actual, false);
-            shiftDistance = AnalyzerCaster.promoteNumeric(rhs.actual, false);
+            promote = locals.getDefinition().caster.promoteNumeric(lhs.actual, false);
+            shiftDistance = locals.getDefinition().caster.promoteNumeric(rhs.actual, false);
             shift = true;
         } else if (operation == Operation.USH) {
-            promote = AnalyzerCaster.promoteNumeric(lhs.actual, false);
-            shiftDistance = AnalyzerCaster.promoteNumeric(rhs.actual, false);
+            promote = locals.getDefinition().caster.promoteNumeric(lhs.actual, false);
+            shiftDistance = locals.getDefinition().caster.promoteNumeric(rhs.actual, false);
             shift = true;
         } else if (operation == Operation.BWAND) {
-            promote = AnalyzerCaster.promoteXor(lhs.actual, rhs.actual);
+            promote = locals.getDefinition().caster.promoteXor(lhs.actual, rhs.actual);
         } else if (operation == Operation.XOR) {
-            promote = AnalyzerCaster.promoteXor(lhs.actual, rhs.actual);
+            promote = locals.getDefinition().caster.promoteXor(lhs.actual, rhs.actual);
         } else if (operation == Operation.BWOR) {
-            promote = AnalyzerCaster.promoteXor(lhs.actual, rhs.actual);
+            promote = locals.getDefinition().caster.promoteXor(lhs.actual, rhs.actual);
         } else {
             throw createError(new IllegalStateException("Illegal tree structure."));
         }
@@ -187,7 +189,7 @@ public final class EAssignment extends AExpression {
                 // shifts are promoted independently, but for the def type, we need object.
                 rhs.expected = promote;
             } else if (shiftDistance.clazz == long.class) {
-                rhs.expected = Definition.INT_TYPE;
+                rhs.expected = locals.getDefinition().intType;
                 rhs.explicit = true;
             } else {
                 rhs.expected = shiftDistance;
@@ -198,11 +200,11 @@ public final class EAssignment extends AExpression {
 
         rhs = rhs.cast(locals);
 
-        there = AnalyzerCaster.getLegalCast(location, lhs.actual, promote, false, false);
-        back = AnalyzerCaster.getLegalCast(location, promote, lhs.actual, true, false);
+        there = locals.getDefinition().caster.getLegalCast(location, lhs.actual, promote, false, false);
+        back = locals.getDefinition().caster.getLegalCast(location, promote, lhs.actual, true, false);
 
         this.statement = true;
-        this.actual = read ? lhs.actual : Definition.VOID_TYPE;
+        this.actual = read ? lhs.actual : locals.getDefinition().voidType;
     }
 
     private void analyzeSimple(Locals locals) {
@@ -222,7 +224,7 @@ public final class EAssignment extends AExpression {
         rhs = rhs.cast(locals);
 
         this.statement = true;
-        this.actual = read ? lhs.actual : Definition.VOID_TYPE;
+        this.actual = read ? lhs.actual : locals.getDefinition().voidType;
     }
 
     /**
@@ -295,8 +297,8 @@ public final class EAssignment extends AExpression {
         // its tricky here as there are possibly explicit casts, too.
         // write the operation instruction for compound assignment
             if (promote.dynamic) {
-                writer.writeDynamicBinaryInstruction(location, promote,
-                    Definition.DEF_TYPE, Definition.DEF_TYPE, operation, DefBootstrap.OPERATOR_COMPOUND_ASSIGNMENT);
+                writer.writeDynamicBinaryInstruction(
+                    location, promote, DefType, DefType, operation, DefBootstrap.OPERATOR_COMPOUND_ASSIGNMENT);
             } else {
                 writer.writeBinaryInstruction(location, promote, operation);
             }

+ 26 - 25
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java

@@ -19,7 +19,6 @@
 
 package org.elasticsearch.painless.node;
 
-import org.elasticsearch.painless.AnalyzerCaster;
 import org.elasticsearch.painless.DefBootstrap;
 import org.elasticsearch.painless.Definition;
 import org.elasticsearch.painless.Definition.Type;
@@ -32,6 +31,8 @@ import org.elasticsearch.painless.WriterConstants;
 
 import java.util.Objects;
 import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * Represents a binary math expression.
@@ -100,7 +101,7 @@ public final class EBinary extends AExpression {
         left.analyze(variables);
         right.analyze(variables);
 
-        promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
+        promote = variables.getDefinition().caster.promoteNumeric(left.actual, right.actual, true);
 
         if (promote == null) {
             throw createError(new ClassCastException("Cannot apply multiply [*] to types " +
@@ -144,7 +145,7 @@ public final class EBinary extends AExpression {
         left.analyze(variables);
         right.analyze(variables);
 
-        promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
+        promote = variables.getDefinition().caster.promoteNumeric(left.actual, right.actual, true);
 
         if (promote == null) {
             throw createError(new ClassCastException("Cannot apply divide [/] to types " +
@@ -193,7 +194,7 @@ public final class EBinary extends AExpression {
         left.analyze(variables);
         right.analyze(variables);
 
-        promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
+        promote = variables.getDefinition().caster.promoteNumeric(left.actual, right.actual, true);
 
         if (promote == null) {
             throw createError(new ClassCastException("Cannot apply remainder [%] to types " +
@@ -242,7 +243,7 @@ public final class EBinary extends AExpression {
         left.analyze(variables);
         right.analyze(variables);
 
-        promote = AnalyzerCaster.promoteAdd(left.actual, right.actual);
+        promote = variables.getDefinition().caster.promoteAdd(left.actual, right.actual);
 
         if (promote == null) {
             throw createError(new ClassCastException("Cannot apply add [+] to types " +
@@ -302,7 +303,7 @@ public final class EBinary extends AExpression {
         left.analyze(variables);
         right.analyze(variables);
 
-        promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
+        promote = variables.getDefinition().caster.promoteNumeric(left.actual, right.actual, true);
 
         if (promote == null) {
             throw createError(new ClassCastException("Cannot apply subtract [-] to types " +
@@ -347,22 +348,22 @@ public final class EBinary extends AExpression {
         left.analyze(variables);
         right.analyze(variables);
 
-        left.expected = Definition.STRING_TYPE;
-        right.expected = Definition.PATTERN_TYPE;
+        left.expected = variables.getDefinition().StringType;
+        right.expected = variables.getDefinition().PatternType;
 
         left = left.cast(variables);
         right = right.cast(variables);
 
-        promote = Definition.BOOLEAN_TYPE;
-        actual = Definition.BOOLEAN_TYPE;
+        promote = variables.getDefinition().booleanType;
+        actual = variables.getDefinition().booleanType;
     }
 
     private void analyzeLSH(Locals variables) {
         left.analyze(variables);
         right.analyze(variables);
 
-        Type lhspromote = AnalyzerCaster.promoteNumeric(left.actual, false);
-        Type rhspromote = AnalyzerCaster.promoteNumeric(right.actual, false);
+        Type lhspromote = variables.getDefinition().caster.promoteNumeric(left.actual, false);
+        Type rhspromote = variables.getDefinition().caster.promoteNumeric(right.actual, false);
 
         if (lhspromote == null || rhspromote == null) {
             throw createError(new ClassCastException("Cannot apply left shift [<<] to types " +
@@ -383,7 +384,7 @@ public final class EBinary extends AExpression {
             left.expected = lhspromote;
 
             if (rhspromote.clazz == long.class) {
-                right.expected = Definition.INT_TYPE;
+                right.expected = variables.getDefinition().intType;
                 right.explicit = true;
             } else {
                 right.expected = rhspromote;
@@ -410,8 +411,8 @@ public final class EBinary extends AExpression {
         left.analyze(variables);
         right.analyze(variables);
 
-        Type lhspromote = AnalyzerCaster.promoteNumeric(left.actual, false);
-        Type rhspromote = AnalyzerCaster.promoteNumeric(right.actual, false);
+        Type lhspromote = variables.getDefinition().caster.promoteNumeric(left.actual, false);
+        Type rhspromote = variables.getDefinition().caster.promoteNumeric(right.actual, false);
 
         if (lhspromote == null || rhspromote == null) {
             throw createError(new ClassCastException("Cannot apply right shift [>>] to types " +
@@ -432,7 +433,7 @@ public final class EBinary extends AExpression {
             left.expected = lhspromote;
 
             if (rhspromote.clazz == long.class) {
-                right.expected = Definition.INT_TYPE;
+                right.expected = variables.getDefinition().intType;
                 right.explicit = true;
             } else {
                 right.expected = rhspromote;
@@ -459,8 +460,8 @@ public final class EBinary extends AExpression {
         left.analyze(variables);
         right.analyze(variables);
 
-        Type lhspromote = AnalyzerCaster.promoteNumeric(left.actual, false);
-        Type rhspromote = AnalyzerCaster.promoteNumeric(right.actual, false);
+        Type lhspromote = variables.getDefinition().caster.promoteNumeric(left.actual, false);
+        Type rhspromote = variables.getDefinition().caster.promoteNumeric(right.actual, false);
 
         actual = promote = lhspromote;
         shiftDistance = rhspromote;
@@ -481,7 +482,7 @@ public final class EBinary extends AExpression {
             left.expected = lhspromote;
 
             if (rhspromote.clazz == long.class) {
-                right.expected = Definition.INT_TYPE;
+                right.expected = variables.getDefinition().intType;
                 right.explicit = true;
             } else {
                 right.expected = rhspromote;
@@ -508,7 +509,7 @@ public final class EBinary extends AExpression {
         left.analyze(variables);
         right.analyze(variables);
 
-        promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, false);
+        promote = variables.getDefinition().caster.promoteNumeric(left.actual, right.actual, false);
 
         if (promote == null) {
             throw createError(new ClassCastException("Cannot apply and [&] to types " +
@@ -549,7 +550,7 @@ public final class EBinary extends AExpression {
         left.analyze(variables);
         right.analyze(variables);
 
-        promote = AnalyzerCaster.promoteXor(left.actual, right.actual);
+        promote = variables.getDefinition().caster.promoteXor(left.actual, right.actual);
 
         if (promote == null) {
             throw createError(new ClassCastException("Cannot apply xor [^] to types " +
@@ -591,7 +592,7 @@ public final class EBinary extends AExpression {
         left.analyze(variables);
         right.analyze(variables);
 
-        promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, false);
+        promote = variables.getDefinition().caster.promoteNumeric(left.actual, right.actual, false);
 
         if (promote == null) {
             throw createError(new ClassCastException("Cannot apply or [|] to types " +
@@ -654,12 +655,12 @@ public final class EBinary extends AExpression {
         } else if (operation == Operation.FIND || operation == Operation.MATCH) {
             right.write(writer, globals);
             left.write(writer, globals);
-            writer.invokeVirtual(Definition.PATTERN_TYPE.type, WriterConstants.PATTERN_MATCHER);
+            writer.invokeVirtual(org.objectweb.asm.Type.getType(Pattern.class), WriterConstants.PATTERN_MATCHER);
 
             if (operation == Operation.FIND) {
-                writer.invokeVirtual(Definition.MATCHER_TYPE.type, WriterConstants.MATCHER_FIND);
+                writer.invokeVirtual(org.objectweb.asm.Type.getType(Matcher.class), WriterConstants.MATCHER_FIND);
             } else if (operation == Operation.MATCH) {
-                writer.invokeVirtual(Definition.MATCHER_TYPE.type, WriterConstants.MATCHER_MATCHES);
+                writer.invokeVirtual(org.objectweb.asm.Type.getType(Matcher.class), WriterConstants.MATCHER_MATCHES);
             } else {
                 throw new IllegalStateException("Illegal tree structure.");
             }

+ 3 - 3
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java

@@ -57,11 +57,11 @@ public final class EBool extends AExpression {
 
     @Override
     void analyze(Locals locals) {
-        left.expected = Definition.BOOLEAN_TYPE;
+        left.expected = locals.getDefinition().booleanType;
         left.analyze(locals);
         left = left.cast(locals);
 
-        right.expected = Definition.BOOLEAN_TYPE;
+        right.expected = locals.getDefinition().booleanType;
         right.analyze(locals);
         right = right.cast(locals);
 
@@ -75,7 +75,7 @@ public final class EBool extends AExpression {
             }
         }
 
-        actual = Definition.BOOLEAN_TYPE;
+        actual = locals.getDefinition().booleanType;
     }
 
     @Override

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java

@@ -49,7 +49,7 @@ public final class EBoolean extends AExpression {
             throw createError(new IllegalArgumentException("Must read from constant [" + constant + "]."));
         }
 
-        actual = Definition.BOOLEAN_TYPE;
+        actual = locals.getDefinition().booleanType;
     }
 
     @Override

+ 3 - 4
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECapturingFunctionRef.java

@@ -34,7 +34,6 @@ import org.objectweb.asm.Type;
 import java.util.Objects;
 import java.util.Set;
 
-import static org.elasticsearch.painless.Definition.VOID_TYPE;
 import static org.elasticsearch.painless.WriterConstants.LAMBDA_BOOTSTRAP_HANDLE;
 
 /**
@@ -83,11 +82,11 @@ public final class ECapturingFunctionRef extends AExpression implements ILambda
                     for (int i = 0; i < ref.interfaceMethod.arguments.size(); ++i) {
                         Definition.Type from = ref.interfaceMethod.arguments.get(i);
                         Definition.Type to = ref.delegateMethod.arguments.get(i);
-                        AnalyzerCaster.getLegalCast(location, from, to, false, true);
+                        locals.getDefinition().caster.getLegalCast(location, from, to, false, true);
                     }
 
-                    if (ref.interfaceMethod.rtn != VOID_TYPE) {
-                        AnalyzerCaster.getLegalCast(location, ref.delegateMethod.rtn, ref.interfaceMethod.rtn, false, true);
+                    if (ref.interfaceMethod.rtn.equals(locals.getDefinition().voidType) == false) {
+                        locals.getDefinition().caster.getLegalCast(location, ref.delegateMethod.rtn, ref.interfaceMethod.rtn, false, true);
                     }
                 } catch (IllegalArgumentException e) {
                     throw createError(e);

+ 16 - 16
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java

@@ -89,7 +89,7 @@ public final class EComp extends AExpression {
         left.analyze(variables);
         right.analyze(variables);
 
-        promotedType = AnalyzerCaster.promoteEquality(left.actual, right.actual);
+        promotedType = variables.getDefinition().caster.promoteEquality(left.actual, right.actual);
 
         if (promotedType == null) {
             throw createError(new ClassCastException("Cannot apply equals [==] to types " +
@@ -133,14 +133,14 @@ public final class EComp extends AExpression {
             }
         }
 
-        actual = Definition.BOOLEAN_TYPE;
+        actual = variables.getDefinition().booleanType;
     }
 
     private void analyzeEqR(Locals variables) {
         left.analyze(variables);
         right.analyze(variables);
 
-        promotedType = AnalyzerCaster.promoteEquality(left.actual, right.actual);
+        promotedType = variables.getDefinition().caster.promoteEquality(left.actual, right.actual);
 
         if (promotedType == null) {
             throw createError(new ClassCastException("Cannot apply reference equals [===] to types " +
@@ -175,14 +175,14 @@ public final class EComp extends AExpression {
             }
         }
 
-        actual = Definition.BOOLEAN_TYPE;
+        actual = variables.getDefinition().booleanType;
     }
 
     private void analyzeNE(Locals variables) {
         left.analyze(variables);
         right.analyze(variables);
 
-        promotedType = AnalyzerCaster.promoteEquality(left.actual, right.actual);
+        promotedType = variables.getDefinition().caster.promoteEquality(left.actual, right.actual);
 
         if (promotedType == null) {
             throw createError(new ClassCastException("Cannot apply not equals [!=] to types " +
@@ -226,14 +226,14 @@ public final class EComp extends AExpression {
             }
         }
 
-        actual = Definition.BOOLEAN_TYPE;
+        actual = variables.getDefinition().booleanType;
     }
 
     private void analyzeNER(Locals variables) {
         left.analyze(variables);
         right.analyze(variables);
 
-        promotedType = AnalyzerCaster.promoteEquality(left.actual, right.actual);
+        promotedType = variables.getDefinition().caster.promoteEquality(left.actual, right.actual);
 
         if (promotedType == null) {
             throw createError(new ClassCastException("Cannot apply reference not equals [!==] to types " +
@@ -268,14 +268,14 @@ public final class EComp extends AExpression {
             }
         }
 
-        actual = Definition.BOOLEAN_TYPE;
+        actual = variables.getDefinition().booleanType;
     }
 
     private void analyzeGTE(Locals variables) {
         left.analyze(variables);
         right.analyze(variables);
 
-        promotedType = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
+        promotedType = variables.getDefinition().caster.promoteNumeric(left.actual, right.actual, true);
 
         if (promotedType == null) {
             throw createError(new ClassCastException("Cannot apply greater than or equals [>=] to types " +
@@ -309,14 +309,14 @@ public final class EComp extends AExpression {
             }
         }
 
-        actual = Definition.BOOLEAN_TYPE;
+        actual = variables.getDefinition().booleanType;
     }
 
     private void analyzeGT(Locals variables) {
         left.analyze(variables);
         right.analyze(variables);
 
-        promotedType = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
+        promotedType = variables.getDefinition().caster.promoteNumeric(left.actual, right.actual, true);
 
         if (promotedType == null) {
             throw createError(new ClassCastException("Cannot apply greater than [>] to types " +
@@ -350,14 +350,14 @@ public final class EComp extends AExpression {
             }
         }
 
-        actual = Definition.BOOLEAN_TYPE;
+        actual = variables.getDefinition().booleanType;
     }
 
     private void analyzeLTE(Locals variables) {
         left.analyze(variables);
         right.analyze(variables);
 
-        promotedType = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
+        promotedType = variables.getDefinition().caster.promoteNumeric(left.actual, right.actual, true);
 
         if (promotedType == null) {
             throw createError(new ClassCastException("Cannot apply less than or equals [<=] to types " +
@@ -391,14 +391,14 @@ public final class EComp extends AExpression {
             }
         }
 
-        actual = Definition.BOOLEAN_TYPE;
+        actual = variables.getDefinition().booleanType;
     }
 
     private void analyzeLT(Locals variables) {
         left.analyze(variables);
         right.analyze(variables);
 
-        promotedType = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true);
+        promotedType = variables.getDefinition().caster.promoteNumeric(left.actual, right.actual, true);
 
         if (promotedType == null) {
             throw createError(new ClassCastException("Cannot apply less than [>=] to types " +
@@ -432,7 +432,7 @@ public final class EComp extends AExpression {
             }
         }
 
-        actual = Definition.BOOLEAN_TYPE;
+        actual = variables.getDefinition().booleanType;
     }
 
     @Override

+ 2 - 2
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java

@@ -59,7 +59,7 @@ public final class EConditional extends AExpression {
 
     @Override
     void analyze(Locals locals) {
-        condition.expected = Definition.BOOLEAN_TYPE;
+        condition.expected = locals.getDefinition().booleanType;
         condition.analyze(locals);
         condition = condition.cast(locals);
 
@@ -79,7 +79,7 @@ public final class EConditional extends AExpression {
         right.analyze(locals);
 
         if (expected == null) {
-            final Type promote = AnalyzerCaster.promoteConditional(left.actual, right.actual, left.constant, right.constant);
+            final Type promote = locals.getDefinition().caster.promoteConditional(left.actual, right.actual, left.constant, right.constant);
 
             left.expected = promote;
             right.expected = promote;

+ 9 - 9
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java

@@ -48,23 +48,23 @@ final class EConstant extends AExpression {
     @Override
     void analyze(Locals locals) {
         if (constant instanceof String) {
-            actual = Definition.STRING_TYPE;
+            actual = locals.getDefinition().StringType;
         } else if (constant instanceof Double) {
-            actual = Definition.DOUBLE_TYPE;
+            actual = locals.getDefinition().doubleType;
         } else if (constant instanceof Float) {
-            actual = Definition.FLOAT_TYPE;
+            actual = locals.getDefinition().floatType;
         } else if (constant instanceof Long) {
-            actual = Definition.LONG_TYPE;
+            actual = locals.getDefinition().longType;
         } else if (constant instanceof Integer) {
-            actual = Definition.INT_TYPE;
+            actual = locals.getDefinition().intType;
         } else if (constant instanceof Character) {
-            actual = Definition.CHAR_TYPE;
+            actual = locals.getDefinition().charType;
         } else if (constant instanceof Short) {
-            actual = Definition.SHORT_TYPE;
+            actual = locals.getDefinition().shortType;
         } else if (constant instanceof Byte) {
-            actual = Definition.BYTE_TYPE;
+            actual = locals.getDefinition().byteType;
         } else if (constant instanceof Boolean) {
-            actual = Definition.BOOLEAN_TYPE;
+            actual = locals.getDefinition().booleanType;
         } else {
             throw createError(new IllegalStateException("Illegal tree structure."));
         }

+ 2 - 2
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java

@@ -53,7 +53,7 @@ public final class EDecimal extends AExpression {
         if (value.endsWith("f") || value.endsWith("F")) {
             try {
                 constant = Float.parseFloat(value.substring(0, value.length() - 1));
-                actual = Definition.FLOAT_TYPE;
+                actual = locals.getDefinition().floatType;
             } catch (NumberFormatException exception) {
                 throw createError(new IllegalArgumentException("Invalid float constant [" + value + "]."));
             }
@@ -64,7 +64,7 @@ public final class EDecimal extends AExpression {
             }
             try {
                 constant = Double.parseDouble(toParse);
-                actual = Definition.DOUBLE_TYPE;
+                actual = locals.getDefinition().doubleType;
             } catch (NumberFormatException exception) {
                 throw createError(new IllegalArgumentException("Invalid double constant [" + value + "]."));
             }

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EElvis.java

@@ -81,7 +81,7 @@ public class EElvis extends AExpression {
         }
 
         if (expected == null) {
-            final Type promote = AnalyzerCaster.promoteConditional(lhs.actual, rhs.actual, lhs.constant, rhs.constant);
+            final Type promote = locals.getDefinition().caster.promoteConditional(lhs.actual, rhs.actual, lhs.constant, rhs.constant);
 
             lhs.expected = promote;
             rhs.expected = promote;

+ 3 - 4
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EFunctionRef.java

@@ -33,7 +33,6 @@ import org.objectweb.asm.Type;
 import java.util.Objects;
 import java.util.Set;
 
-import static org.elasticsearch.painless.Definition.VOID_TYPE;
 import static org.elasticsearch.painless.WriterConstants.LAMBDA_BOOTSTRAP_HANDLE;
 
 /**
@@ -83,11 +82,11 @@ public final class EFunctionRef extends AExpression implements ILambda {
                     for (int i = 0; i < interfaceMethod.arguments.size(); ++i) {
                         Definition.Type from = interfaceMethod.arguments.get(i);
                         Definition.Type to = delegateMethod.arguments.get(i);
-                        AnalyzerCaster.getLegalCast(location, from, to, false, true);
+                        locals.getDefinition().caster.getLegalCast(location, from, to, false, true);
                     }
 
-                    if (interfaceMethod.rtn != VOID_TYPE) {
-                        AnalyzerCaster.getLegalCast(location, delegateMethod.rtn, interfaceMethod.rtn, false, true);
+                    if (interfaceMethod.rtn.equals(locals.getDefinition().voidType) == false) {
+                        locals.getDefinition().caster.getLegalCast(location, delegateMethod.rtn, interfaceMethod.rtn, false, true);
                     }
                 } else {
                     // whitelist lookup

+ 3 - 3
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java

@@ -65,7 +65,7 @@ public final class EInstanceof extends AExpression {
         }
 
         // map to wrapped type for primitive types
-        resolvedType = type.clazz.isPrimitive() ? Definition.getBoxedType(type).clazz : type.clazz;
+        resolvedType = type.clazz.isPrimitive() ? locals.getDefinition().getBoxedType(type).clazz : type.clazz;
 
         // analyze and cast the expression
         expression.analyze(locals);
@@ -75,9 +75,9 @@ public final class EInstanceof extends AExpression {
         // record if the expression returns a primitive
         primitiveExpression = expression.actual.clazz.isPrimitive();
         // map to wrapped type for primitive types
-        expressionType = expression.actual.clazz.isPrimitive() ? Definition.getBoxedType(expression.actual).clazz : type.clazz;
+        expressionType = expression.actual.clazz.isPrimitive() ? locals.getDefinition().getBoxedType(expression.actual).clazz : type.clazz;
 
-        actual = Definition.BOOLEAN_TYPE;
+        actual = locals.getDefinition().booleanType;
     }
 
     @Override

+ 6 - 9
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ELambda.java

@@ -39,10 +39,7 @@ import java.util.List;
 import java.util.Objects;
 import java.util.Set;
 
-import static org.elasticsearch.painless.Definition.VOID_TYPE;
-import static org.elasticsearch.painless.WriterConstants.CLASS_NAME;
 import static org.elasticsearch.painless.WriterConstants.LAMBDA_BOOTSTRAP_HANDLE;
-import static org.objectweb.asm.Opcodes.H_INVOKESTATIC;
 
 /**
  * Lambda expression node.
@@ -111,7 +108,7 @@ public final class ELambda extends AExpression implements ILambda {
         if (expected == null) {
             interfaceMethod = null;
             // we don't know anything: treat as def
-            returnType = Definition.DEF_TYPE;
+            returnType = locals.getDefinition().DefType;
             // don't infer any types, replace any null types with def
             actualParamTypeStrs = new ArrayList<>(paramTypeStrs.size());
             for (String type : paramTypeStrs) {
@@ -133,8 +130,8 @@ public final class ELambda extends AExpression implements ILambda {
                 throw new IllegalArgumentException("Incorrect number of parameters for [" + interfaceMethod.name +
                                                    "] in [" + expected.clazz + "]");
             // for method invocation, its allowed to ignore the return value
-            if (interfaceMethod.rtn == Definition.VOID_TYPE) {
-                returnType = Definition.DEF_TYPE;
+            if (interfaceMethod.rtn.equals(locals.getDefinition().voidType)) {
+                returnType = locals.getDefinition().DefType;
             } else {
                 returnType = interfaceMethod.rtn;
             }
@@ -195,11 +192,11 @@ public final class ELambda extends AExpression implements ILambda {
             for (int i = 0; i < interfaceMethod.arguments.size(); ++i) {
                 Type from = interfaceMethod.arguments.get(i);
                 Type to = desugared.parameters.get(i + captures.size()).type;
-                AnalyzerCaster.getLegalCast(location, from, to, false, true);
+                locals.getDefinition().caster.getLegalCast(location, from, to, false, true);
             }
 
-            if (interfaceMethod.rtn != VOID_TYPE) {
-                AnalyzerCaster.getLegalCast(location, desugared.rtnType, interfaceMethod.rtn, false, true);
+            if (interfaceMethod.rtn.equals(locals.getDefinition().voidType) == false) {
+                locals.getDefinition().caster.getLegalCast(location, desugared.rtnType, interfaceMethod.rtn, false, true);
             }
 
             actual = expected;

+ 2 - 2
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EListInit.java

@@ -58,7 +58,7 @@ public final class EListInit extends AExpression {
             throw createError(new IllegalArgumentException("Must read from list initializer."));
         }
 
-        actual = Definition.ARRAY_LIST_TYPE;
+        actual = locals.getDefinition().ArrayListType;
 
         constructor = actual.struct.constructors.get(new MethodKey("<init>", 0));
 
@@ -75,7 +75,7 @@ public final class EListInit extends AExpression {
         for (int index = 0; index < values.size(); ++index) {
             AExpression expression = values.get(index);
 
-            expression.expected = Definition.DEF_TYPE;
+            expression.expected = locals.getDefinition().DefType;
             expression.internal = true;
             expression.analyze(locals);
             values.set(index, expression.cast(locals));

+ 3 - 3
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EMapInit.java

@@ -64,7 +64,7 @@ public final class EMapInit extends AExpression {
             throw createError(new IllegalArgumentException("Must read from map initializer."));
         }
 
-        actual = Definition.HASH_MAP_TYPE;
+        actual = locals.getDefinition().HashMapType;
 
         constructor = actual.struct.constructors.get(new MethodKey("<init>", 0));
 
@@ -85,7 +85,7 @@ public final class EMapInit extends AExpression {
         for (int index = 0; index < keys.size(); ++index) {
             AExpression expression = keys.get(index);
 
-            expression.expected = Definition.DEF_TYPE;
+            expression.expected = locals.getDefinition().DefType;
             expression.internal = true;
             expression.analyze(locals);
             keys.set(index, expression.cast(locals));
@@ -94,7 +94,7 @@ public final class EMapInit extends AExpression {
         for (int index = 0; index < values.size(); ++index) {
             AExpression expression = values.get(index);
 
-            expression.expected = Definition.DEF_TYPE;
+            expression.expected = locals.getDefinition().DefType;
             expression.internal = true;
             expression.analyze(locals);
             values.set(index, expression.cast(locals));

+ 1 - 2
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewArray.java

@@ -71,8 +71,7 @@ public final class ENewArray extends AExpression {
         for (int argument = 0; argument < arguments.size(); ++argument) {
             AExpression expression = arguments.get(argument);
 
-            expression.expected = initialize ? locals.getDefinition().getType(type.struct, 0)
-                    : Definition.INT_TYPE;
+            expression.expected = initialize ? locals.getDefinition().getType(type.struct, 0) : locals.getDefinition().intType;
             expression.internal = true;
             expression.analyze(locals);
             arguments.set(argument, expression.cast(locals));

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java

@@ -58,7 +58,7 @@ public final class ENull extends AExpression {
 
             actual = expected;
         } else {
-            actual = Definition.OBJECT_TYPE;
+            actual = locals.getDefinition().ObjectType;
         }
     }
 

+ 7 - 7
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java

@@ -62,7 +62,7 @@ public final class ENumeric extends AExpression {
 
             try {
                 constant = Double.parseDouble(value.substring(0, value.length() - 1));
-                actual = Definition.DOUBLE_TYPE;
+                actual = locals.getDefinition().doubleType;
             } catch (NumberFormatException exception) {
                 throw createError(new IllegalArgumentException("Invalid double constant [" + value + "]."));
             }
@@ -73,14 +73,14 @@ public final class ENumeric extends AExpression {
 
             try {
                 constant = Float.parseFloat(value.substring(0, value.length() - 1));
-                actual = Definition.FLOAT_TYPE;
+                actual = locals.getDefinition().floatType;
             } catch (NumberFormatException exception) {
                 throw createError(new IllegalArgumentException("Invalid float constant [" + value + "]."));
             }
         } else if (value.endsWith("l") || value.endsWith("L")) {
             try {
                 constant = Long.parseLong(value.substring(0, value.length() - 1), radix);
-                actual = Definition.LONG_TYPE;
+                actual = locals.getDefinition().longType;
             } catch (NumberFormatException exception) {
                 throw createError(new IllegalArgumentException("Invalid long constant [" + value + "]."));
             }
@@ -91,16 +91,16 @@ public final class ENumeric extends AExpression {
 
                 if (sort == byte.class && integer >= Byte.MIN_VALUE && integer <= Byte.MAX_VALUE) {
                     constant = (byte)integer;
-                    actual = Definition.BYTE_TYPE;
+                    actual = locals.getDefinition().byteType;
                 } else if (sort == char.class && integer >= Character.MIN_VALUE && integer <= Character.MAX_VALUE) {
                     constant = (char)integer;
-                    actual = Definition.CHAR_TYPE;
+                    actual = locals.getDefinition().charType;
                 } else if (sort == short.class && integer >= Short.MIN_VALUE && integer <= Short.MAX_VALUE) {
                     constant = (short)integer;
-                    actual = Definition.SHORT_TYPE;
+                    actual = locals.getDefinition().shortType;
                 } else {
                     constant = integer;
-                    actual = Definition.INT_TYPE;
+                    actual = locals.getDefinition().intType;
                 }
             } catch (NumberFormatException exception) {
                 try {

+ 5 - 4
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ERegex.java

@@ -73,22 +73,23 @@ public final class ERegex extends AExpression {
                     new IllegalArgumentException("Error compiling regex: " + e.getDescription()));
         }
 
-        constant = new Constant(location, Definition.PATTERN_TYPE.type, "regexAt$" + location.getOffset(), this::initializeConstant);
-        actual = Definition.PATTERN_TYPE;
+        constant = new Constant(
+            location, locals.getDefinition().PatternType.type, "regexAt$" + location.getOffset(), this::initializeConstant);
+        actual = locals.getDefinition().PatternType;
     }
 
     @Override
     void write(MethodWriter writer, Globals globals) {
         writer.writeDebugInfo(location);
 
-        writer.getStatic(WriterConstants.CLASS_TYPE, constant.name, Definition.PATTERN_TYPE.type);
+        writer.getStatic(WriterConstants.CLASS_TYPE, constant.name, org.objectweb.asm.Type.getType(Pattern.class));
         globals.addConstantInitializer(constant);
     }
 
     private void initializeConstant(MethodWriter writer) {
         writer.push(pattern);
         writer.push(flags);
-        writer.invokeStatic(Definition.PATTERN_TYPE.type, WriterConstants.PATTERN_COMPILE);
+        writer.invokeStatic(org.objectweb.asm.Type.getType(Pattern.class), WriterConstants.PATTERN_COMPILE);
     }
 
     private int flagForChar(char c) {

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EString.java

@@ -50,7 +50,7 @@ public final class EString extends AExpression {
             throw createError(new IllegalArgumentException("Must read from constant [" + constant + "]."));
         }
 
-        actual = Definition.STRING_TYPE;
+        actual = locals.getDefinition().StringType;
     }
 
     @Override

+ 5 - 5
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java

@@ -76,7 +76,7 @@ public final class EUnary extends AExpression {
     }
 
     void analyzeNot(Locals variables) {
-        child.expected = Definition.BOOLEAN_TYPE;
+        child.expected = variables.getDefinition().booleanType;
         child.analyze(variables);
         child = child.cast(variables);
 
@@ -84,13 +84,13 @@ public final class EUnary extends AExpression {
             constant = !(boolean)child.constant;
         }
 
-        actual = Definition.BOOLEAN_TYPE;
+        actual = variables.getDefinition().booleanType;
     }
 
     void analyzeBWNot(Locals variables) {
         child.analyze(variables);
 
-        promote = AnalyzerCaster.promoteNumeric(child.actual, false);
+        promote = variables.getDefinition().caster.promoteNumeric(child.actual, false);
 
         if (promote == null) {
             throw createError(new ClassCastException("Cannot apply not [~] to type [" + child.actual.name + "]."));
@@ -121,7 +121,7 @@ public final class EUnary extends AExpression {
     void analyzerAdd(Locals variables) {
         child.analyze(variables);
 
-        promote = AnalyzerCaster.promoteNumeric(child.actual, true);
+        promote = variables.getDefinition().caster.promoteNumeric(child.actual, true);
 
         if (promote == null) {
             throw createError(new ClassCastException("Cannot apply positive [+] to type [" + child.actual.name + "]."));
@@ -156,7 +156,7 @@ public final class EUnary extends AExpression {
     void analyzerSub(Locals variables) {
         child.analyze(variables);
 
-        promote = AnalyzerCaster.promoteNumeric(child.actual, true);
+        promote = variables.getDefinition().caster.promoteNumeric(child.actual, true);
 
         if (promote == null) {
             throw createError(new ClassCastException("Cannot apply negative [-] to type [" + child.actual.name + "]."));

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java

@@ -73,7 +73,7 @@ public final class PCallInvoke extends AExpression {
         Struct struct = prefix.actual.struct;
 
         if (prefix.actual.clazz.isPrimitive()) {
-            struct = Definition.getBoxedType(prefix.actual).struct;
+            struct = locals.getDefinition().getBoxedType(prefix.actual).struct;
         }
 
         MethodKey methodKey = new MethodKey(name, arguments.size());

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubArrayLength.java

@@ -56,7 +56,7 @@ final class PSubArrayLength extends AStoreable {
                 throw createError(new IllegalArgumentException("Cannot write to read-only field [length] for an array."));
             }
 
-            actual = Definition.INT_TYPE;
+            actual = locals.getDefinition().intType;
         } else {
             throw createError(new IllegalArgumentException("Field [" + value + "] does not exist for type [" + type + "]."));
         }

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubBrace.java

@@ -51,7 +51,7 @@ final class PSubBrace extends AStoreable {
 
     @Override
     void analyze(Locals locals) {
-        index.expected = Definition.INT_TYPE;
+        index.expected = locals.getDefinition().intType;
         index.analyze(locals);
         index = index.cast(locals);
 

+ 5 - 4
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefArray.java

@@ -53,7 +53,7 @@ final class PSubDefArray extends AStoreable {
         index.expected = index.actual;
         index = index.cast(locals);
 
-        actual = expected == null || explicit ? Definition.DEF_TYPE : expected;
+        actual = expected == null || explicit ? locals.getDefinition().DefType : expected;
     }
 
     @Override
@@ -83,7 +83,7 @@ final class PSubDefArray extends AStoreable {
         writer.dup();                                                                     // def, def
         index.write(writer, globals);                                                     // def, def, unnormalized_index
         org.objectweb.asm.Type methodType = org.objectweb.asm.Type.getMethodType(
-                index.actual.type, Definition.DEF_TYPE.type, index.actual.type);
+                index.actual.type, org.objectweb.asm.Type.getType(Object.class), index.actual.type);
         writer.invokeDefCall("normalizeIndex", methodType, DefBootstrap.INDEX_NORMALIZE); // def, normalized_index
     }
 
@@ -92,7 +92,7 @@ final class PSubDefArray extends AStoreable {
         writer.writeDebugInfo(location);
 
         org.objectweb.asm.Type methodType =
-            org.objectweb.asm.Type.getMethodType(actual.type, Definition.DEF_TYPE.type, index.actual.type);
+            org.objectweb.asm.Type.getMethodType(actual.type, org.objectweb.asm.Type.getType(Object.class), index.actual.type);
         writer.invokeDefCall("arrayLoad", methodType, DefBootstrap.ARRAY_LOAD);
     }
 
@@ -101,7 +101,8 @@ final class PSubDefArray extends AStoreable {
         writer.writeDebugInfo(location);
 
         org.objectweb.asm.Type methodType =
-            org.objectweb.asm.Type.getMethodType(Definition.VOID_TYPE.type, Definition.DEF_TYPE.type, index.actual.type, actual.type);
+            org.objectweb.asm.Type.getMethodType(
+                org.objectweb.asm.Type.getType(void.class), org.objectweb.asm.Type.getType(Object.class), index.actual.type, actual.type);
         writer.invokeDefCall("arrayStore", methodType, DefBootstrap.ARRAY_STORE);
     }
 

+ 2 - 2
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefCall.java

@@ -80,7 +80,7 @@ final class PSubDefCall extends AExpression {
             arguments.set(argument, expression.cast(locals));
         }
 
-        actual = expected == null || explicit ? Definition.DEF_TYPE : expected;
+        actual = expected == null || explicit ? locals.getDefinition().DefType : expected;
     }
 
     @Override
@@ -90,7 +90,7 @@ final class PSubDefCall extends AExpression {
         List<Type> parameterTypes = new ArrayList<>();
 
         // first parameter is the receiver, we never know its type: always Object
-        parameterTypes.add(Definition.DEF_TYPE.type);
+        parameterTypes.add(org.objectweb.asm.Type.getType(Object.class));
 
         // append each argument
         for (AExpression argument : arguments) {

+ 5 - 5
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubDefField.java

@@ -50,7 +50,7 @@ final class PSubDefField extends AStoreable {
 
     @Override
     void analyze(Locals locals) {
-        actual = expected == null || explicit ? Definition.DEF_TYPE : expected;
+        actual = expected == null || explicit ? locals.getDefinition().DefType : expected;
     }
 
     @Override
@@ -58,7 +58,7 @@ final class PSubDefField extends AStoreable {
         writer.writeDebugInfo(location);
 
         org.objectweb.asm.Type methodType =
-            org.objectweb.asm.Type.getMethodType(actual.type, Definition.DEF_TYPE.type);
+            org.objectweb.asm.Type.getMethodType(actual.type, org.objectweb.asm.Type.getType(Object.class));
         writer.invokeDefCall(value, methodType, DefBootstrap.LOAD);
     }
 
@@ -87,7 +87,7 @@ final class PSubDefField extends AStoreable {
         writer.writeDebugInfo(location);
 
         org.objectweb.asm.Type methodType =
-            org.objectweb.asm.Type.getMethodType(actual.type, Definition.DEF_TYPE.type);
+            org.objectweb.asm.Type.getMethodType(actual.type, org.objectweb.asm.Type.getType(Object.class));
         writer.invokeDefCall(value, methodType, DefBootstrap.LOAD);
     }
 
@@ -95,8 +95,8 @@ final class PSubDefField extends AStoreable {
     void store(MethodWriter writer, Globals globals) {
         writer.writeDebugInfo(location);
 
-        org.objectweb.asm.Type methodType =
-            org.objectweb.asm.Type.getMethodType(Definition.VOID_TYPE.type, Definition.DEF_TYPE.type, actual.type);
+        org.objectweb.asm.Type methodType = org.objectweb.asm.Type.getMethodType(
+            org.objectweb.asm.Type.getType(void.class), org.objectweb.asm.Type.getType(Object.class), actual.type);
         writer.invokeDefCall(value, methodType, DefBootstrap.STORE);
     }
 

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubListShortcut.java

@@ -75,7 +75,7 @@ final class PSubListShortcut extends AStoreable {
         }
 
         if ((read || write) && (!read || getter != null) && (!write || setter != null)) {
-            index.expected = Definition.INT_TYPE;
+            index.expected = locals.getDefinition().intType;
             index.analyze(locals);
             index = index.cast(locals);
 

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java

@@ -73,7 +73,7 @@ public final class SDo extends AStatement {
             throw createError(new IllegalArgumentException("Extraneous do while loop."));
         }
 
-        condition.expected = Definition.BOOLEAN_TYPE;
+        condition.expected = locals.getDefinition().booleanType;
         condition.analyze(locals);
         condition = condition.cast(locals);
 

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java

@@ -94,7 +94,7 @@ public final class SFor extends AStatement {
         }
 
         if (condition != null) {
-            condition.expected = Definition.BOOLEAN_TYPE;
+            condition.expected = locals.getDefinition().booleanType;
             condition.analyze(locals);
             condition = condition.cast(locals);
 

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIf.java

@@ -56,7 +56,7 @@ public final class SIf extends AStatement {
 
     @Override
     void analyze(Locals locals) {
-        condition.expected = Definition.BOOLEAN_TYPE;
+        condition.expected = locals.getDefinition().booleanType;
         condition.analyze(locals);
         condition = condition.cast(locals);
 

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java

@@ -65,7 +65,7 @@ public final class SIfElse extends AStatement {
 
     @Override
     void analyze(Locals locals) {
-        condition.expected = Definition.BOOLEAN_TYPE;
+        condition.expected = locals.getDefinition().booleanType;
         condition.analyze(locals);
         condition = condition.cast(locals);
 

+ 2 - 2
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachArray.java

@@ -66,11 +66,11 @@ final class SSubEachArray extends AStatement {
         // also add the location offset to make the names unique in case of nested for each loops.
         array = locals.addVariable(location, expression.actual, "#array" + location.getOffset(),
                 true);
-        index = locals.addVariable(location, Definition.INT_TYPE, "#index" + location.getOffset(),
+        index = locals.addVariable(location, locals.getDefinition().intType, "#index" + location.getOffset(),
                 true);
         indexed = locals.getDefinition().getType(expression.actual.struct,
                 expression.actual.dimensions - 1);
-        cast = AnalyzerCaster.getLegalCast(location, indexed, variable.type, true, true);
+        cast = locals.getDefinition().caster.getLegalCast(location, indexed, variable.type, true, true);
     }
 
     @Override

+ 3 - 2
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachIterable.java

@@ -33,6 +33,7 @@ import org.elasticsearch.painless.MethodWriter;
 import org.objectweb.asm.Label;
 import org.objectweb.asm.Opcodes;
 
+import java.util.Iterator;
 import java.util.Objects;
 import java.util.Set;
 
@@ -84,7 +85,7 @@ final class SSubEachIterable extends AStatement {
             }
         }
 
-        cast = AnalyzerCaster.getLegalCast(location, Definition.DEF_TYPE, variable.type, true, true);
+        cast = locals.getDefinition().caster.getLegalCast(location, locals.getDefinition().DefType, variable.type, true, true);
     }
 
     @Override
@@ -95,7 +96,7 @@ final class SSubEachIterable extends AStatement {
 
         if (method == null) {
             org.objectweb.asm.Type methodType = org.objectweb.asm.Type
-                    .getMethodType(Definition.ITERATOR_TYPE.type, Definition.DEF_TYPE.type);
+                    .getMethodType(org.objectweb.asm.Type.getType(Iterator.class), org.objectweb.asm.Type.getType(Object.class));
             writer.invokeDefCall("iterator", methodType, DefBootstrap.ITERATOR);
         } else {
             method.write(writer);

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java

@@ -48,7 +48,7 @@ public final class SThrow extends AStatement {
 
     @Override
     void analyze(Locals locals) {
-        expression.expected = Definition.EXCEPTION_TYPE;
+        expression.expected = locals.getDefinition().ExceptionType;
         expression.analyze(locals);
         expression = expression.cast(locals);
 

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java

@@ -59,7 +59,7 @@ public final class SWhile extends AStatement {
     void analyze(Locals locals) {
         locals = Locals.newLocalScope(locals);
 
-        condition.expected = Definition.BOOLEAN_TYPE;
+        condition.expected = locals.getDefinition().booleanType;
         condition.analyze(locals);
         condition = condition.cast(locals);
 

+ 41 - 48
modules/lang-painless/src/test/java/org/elasticsearch/painless/AnalyzerCasterTests.java

@@ -23,13 +23,6 @@ import org.elasticsearch.painless.Definition.Cast;
 import org.elasticsearch.painless.Definition.Type;
 import org.elasticsearch.test.ESTestCase;
 
-import static org.elasticsearch.painless.Definition.BYTE_TYPE;
-import static org.elasticsearch.painless.Definition.DOUBLE_TYPE;
-import static org.elasticsearch.painless.Definition.FLOAT_TYPE;
-import static org.elasticsearch.painless.Definition.INT_TYPE;
-import static org.elasticsearch.painless.Definition.LONG_TYPE;
-import static org.elasticsearch.painless.Definition.SHORT_TYPE;
-
 public class AnalyzerCasterTests extends ESTestCase {
 
     private static void assertCast(Type actual, Type expected, boolean mustBeExplicit) {
@@ -37,68 +30,68 @@ public class AnalyzerCasterTests extends ESTestCase {
 
         if (actual.equals(expected)) {
             assertFalse(mustBeExplicit);
-            assertNull(AnalyzerCaster.getLegalCast(location, actual, expected, false, false));
-            assertNull(AnalyzerCaster.getLegalCast(location, actual, expected, true, false));
+            assertNull(Definition.DEFINITION.caster.getLegalCast(location, actual, expected, false, false));
+            assertNull(Definition.DEFINITION.caster.getLegalCast(location, actual, expected, true, false));
             return;
         }
 
-        Cast cast = AnalyzerCaster.getLegalCast(location, actual, expected, true, false);
+        Cast cast = Definition.DEFINITION.caster.getLegalCast(location, actual, expected, true, false);
         assertEquals(actual, cast.from);
         assertEquals(expected, cast.to);
 
         if (mustBeExplicit) {
             ClassCastException error = expectThrows(ClassCastException.class,
-                    () -> AnalyzerCaster.getLegalCast(location, actual, expected, false, false));
+                    () -> Definition.DEFINITION.caster.getLegalCast(location, actual, expected, false, false));
             assertTrue(error.getMessage().startsWith("Cannot cast"));
         } else {
-            cast = AnalyzerCaster.getLegalCast(location, actual, expected, false, false);
+            cast = Definition.DEFINITION.caster.getLegalCast(location, actual, expected, false, false);
             assertEquals(actual, cast.from);
             assertEquals(expected, cast.to);
         }
     }
 
     public void testNumericCasts() {
-        assertCast(BYTE_TYPE, BYTE_TYPE, false);
-        assertCast(BYTE_TYPE, SHORT_TYPE, false);
-        assertCast(BYTE_TYPE, INT_TYPE, false);
-        assertCast(BYTE_TYPE, LONG_TYPE, false);
-        assertCast(BYTE_TYPE, FLOAT_TYPE, false);
-        assertCast(BYTE_TYPE, DOUBLE_TYPE, false);
+        assertCast(Definition.DEFINITION.byteType, Definition.DEFINITION.byteType, false);
+        assertCast(Definition.DEFINITION.byteType, Definition.DEFINITION.shortType, false);
+        assertCast(Definition.DEFINITION.byteType, Definition.DEFINITION.intType, false);
+        assertCast(Definition.DEFINITION.byteType, Definition.DEFINITION.longType, false);
+        assertCast(Definition.DEFINITION.byteType, Definition.DEFINITION.floatType, false);
+        assertCast(Definition.DEFINITION.byteType, Definition.DEFINITION.doubleType, false);
 
-        assertCast(SHORT_TYPE, BYTE_TYPE, true);
-        assertCast(SHORT_TYPE, SHORT_TYPE, false);
-        assertCast(SHORT_TYPE, INT_TYPE, false);
-        assertCast(SHORT_TYPE, LONG_TYPE, false);
-        assertCast(SHORT_TYPE, FLOAT_TYPE, false);
-        assertCast(SHORT_TYPE, DOUBLE_TYPE, false);
+        assertCast(Definition.DEFINITION.shortType, Definition.DEFINITION.byteType, true);
+        assertCast(Definition.DEFINITION.shortType, Definition.DEFINITION.shortType, false);
+        assertCast(Definition.DEFINITION.shortType, Definition.DEFINITION.intType, false);
+        assertCast(Definition.DEFINITION.shortType, Definition.DEFINITION.longType, false);
+        assertCast(Definition.DEFINITION.shortType, Definition.DEFINITION.floatType, false);
+        assertCast(Definition.DEFINITION.shortType, Definition.DEFINITION.doubleType, false);
 
-        assertCast(INT_TYPE, BYTE_TYPE, true);
-        assertCast(INT_TYPE, SHORT_TYPE, true);
-        assertCast(INT_TYPE, INT_TYPE, false);
-        assertCast(INT_TYPE, LONG_TYPE, false);
-        assertCast(INT_TYPE, FLOAT_TYPE, false);
-        assertCast(INT_TYPE, DOUBLE_TYPE, false);
+        assertCast(Definition.DEFINITION.intType, Definition.DEFINITION.byteType, true);
+        assertCast(Definition.DEFINITION.intType, Definition.DEFINITION.shortType, true);
+        assertCast(Definition.DEFINITION.intType, Definition.DEFINITION.intType, false);
+        assertCast(Definition.DEFINITION.intType, Definition.DEFINITION.longType, false);
+        assertCast(Definition.DEFINITION.intType, Definition.DEFINITION.floatType, false);
+        assertCast(Definition.DEFINITION.intType, Definition.DEFINITION.doubleType, false);
 
-        assertCast(LONG_TYPE, BYTE_TYPE, true);
-        assertCast(LONG_TYPE, SHORT_TYPE, true);
-        assertCast(LONG_TYPE, INT_TYPE, true);
-        assertCast(LONG_TYPE, LONG_TYPE, false);
-        assertCast(LONG_TYPE, FLOAT_TYPE, false);
-        assertCast(LONG_TYPE, DOUBLE_TYPE, false);
+        assertCast(Definition.DEFINITION.longType, Definition.DEFINITION.byteType, true);
+        assertCast(Definition.DEFINITION.longType, Definition.DEFINITION.shortType, true);
+        assertCast(Definition.DEFINITION.longType, Definition.DEFINITION.intType, true);
+        assertCast(Definition.DEFINITION.longType, Definition.DEFINITION.longType, false);
+        assertCast(Definition.DEFINITION.longType, Definition.DEFINITION.floatType, false);
+        assertCast(Definition.DEFINITION.longType, Definition.DEFINITION.doubleType, false);
 
-        assertCast(FLOAT_TYPE, BYTE_TYPE, true);
-        assertCast(FLOAT_TYPE, SHORT_TYPE, true);
-        assertCast(FLOAT_TYPE, INT_TYPE, true);
-        assertCast(FLOAT_TYPE, LONG_TYPE, true);
-        assertCast(FLOAT_TYPE, FLOAT_TYPE, false);
-        assertCast(FLOAT_TYPE, DOUBLE_TYPE, false);
+        assertCast(Definition.DEFINITION.floatType, Definition.DEFINITION.byteType, true);
+        assertCast(Definition.DEFINITION.floatType, Definition.DEFINITION.shortType, true);
+        assertCast(Definition.DEFINITION.floatType, Definition.DEFINITION.intType, true);
+        assertCast(Definition.DEFINITION.floatType, Definition.DEFINITION.longType, true);
+        assertCast(Definition.DEFINITION.floatType, Definition.DEFINITION.floatType, false);
+        assertCast(Definition.DEFINITION.floatType, Definition.DEFINITION.doubleType, false);
 
-        assertCast(DOUBLE_TYPE, BYTE_TYPE, true);
-        assertCast(DOUBLE_TYPE, SHORT_TYPE, true);
-        assertCast(DOUBLE_TYPE, INT_TYPE, true);
-        assertCast(DOUBLE_TYPE, LONG_TYPE, true);
-        assertCast(DOUBLE_TYPE, FLOAT_TYPE, true);
-        assertCast(DOUBLE_TYPE, DOUBLE_TYPE, false);
+        assertCast(Definition.DEFINITION.doubleType, Definition.DEFINITION.byteType, true);
+        assertCast(Definition.DEFINITION.doubleType, Definition.DEFINITION.shortType, true);
+        assertCast(Definition.DEFINITION.doubleType, Definition.DEFINITION.intType, true);
+        assertCast(Definition.DEFINITION.doubleType, Definition.DEFINITION.longType, true);
+        assertCast(Definition.DEFINITION.doubleType, Definition.DEFINITION.floatType, true);
+        assertCast(Definition.DEFINITION.doubleType, Definition.DEFINITION.doubleType, false);
     }
 
 }

+ 22 - 22
modules/lang-painless/src/test/java/org/elasticsearch/painless/BaseClassTests.java

@@ -66,7 +66,7 @@ public class BaseClassTests extends ScriptTestCase {
     }
 
     public void testGets() {
-        Compiler compiler = new Compiler(Gets.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(Gets.class, Definition.DEFINITION);
         Map<String, Object> map = new HashMap<>();
         map.put("s", 1);
 
@@ -84,7 +84,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract Object execute();
     }
     public void testNoArgs() {
-        Compiler compiler = new Compiler(NoArgs.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(NoArgs.class, Definition.DEFINITION);
         assertEquals(1, ((NoArgs)scriptEngine.compile(compiler, null, "1", emptyMap())).execute());
         assertEquals("foo", ((NoArgs)scriptEngine.compile(compiler, null, "'foo'", emptyMap())).execute());
 
@@ -108,13 +108,13 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract Object execute(Object arg);
     }
     public void testOneArg() {
-        Compiler compiler = new Compiler(OneArg.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(OneArg.class, Definition.DEFINITION);
         Object rando = randomInt();
         assertEquals(rando, ((OneArg)scriptEngine.compile(compiler, null, "arg", emptyMap())).execute(rando));
         rando = randomAlphaOfLength(5);
         assertEquals(rando, ((OneArg)scriptEngine.compile(compiler, null, "arg", emptyMap())).execute(rando));
 
-        Compiler noargs = new Compiler(NoArgs.class, Definition.BUILTINS);
+        Compiler noargs = new Compiler(NoArgs.class, Definition.DEFINITION);
         Exception e = expectScriptThrows(IllegalArgumentException.class, () ->
                 scriptEngine.compile(noargs, null, "doc", emptyMap()));
         assertEquals("Variable [doc] is not defined.", e.getMessage());
@@ -129,7 +129,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract Object execute(String[] arg);
     }
     public void testArrayArg() {
-        Compiler compiler = new Compiler(ArrayArg.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(ArrayArg.class, Definition.DEFINITION);
         String rando = randomAlphaOfLength(5);
         assertEquals(rando, ((ArrayArg)scriptEngine.compile(compiler, null, "arg[0]", emptyMap())).execute(new String[] {rando, "foo"}));
     }
@@ -139,7 +139,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract Object execute(int[] arg);
     }
     public void testPrimitiveArrayArg() {
-        Compiler compiler = new Compiler(PrimitiveArrayArg.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(PrimitiveArrayArg.class, Definition.DEFINITION);
         int rando = randomInt();
         assertEquals(rando, ((PrimitiveArrayArg)scriptEngine.compile(compiler, null, "arg[0]", emptyMap())).execute(new int[] {rando, 10}));
     }
@@ -149,7 +149,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract Object execute(Object[] arg);
     }
     public void testDefArrayArg() {
-        Compiler compiler = new Compiler(DefArrayArg.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(DefArrayArg.class, Definition.DEFINITION);
         Object rando = randomInt();
         assertEquals(rando, ((DefArrayArg)scriptEngine.compile(compiler, null, "arg[0]", emptyMap())).execute(new Object[] {rando, 10}));
         rando = randomAlphaOfLength(5);
@@ -167,7 +167,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract boolean needsD();
     }
     public void testManyArgs() {
-        Compiler compiler = new Compiler(ManyArgs.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(ManyArgs.class, Definition.DEFINITION);
         int rando = randomInt();
         assertEquals(rando, ((ManyArgs)scriptEngine.compile(compiler, null, "a", emptyMap())).execute(rando, 0, 0, 0));
         assertEquals(10, ((ManyArgs)scriptEngine.compile(compiler, null, "a + b + c + d", emptyMap())).execute(1, 2, 3, 4));
@@ -195,7 +195,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract Object execute(String... arg);
     }
     public void testVararg() {
-        Compiler compiler = new Compiler(VarargTest.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(VarargTest.class, Definition.DEFINITION);
         assertEquals("foo bar baz", ((VarargTest)scriptEngine.compile(compiler, null, "String.join(' ', Arrays.asList(arg))", emptyMap()))
                     .execute("foo", "bar", "baz"));
     }
@@ -211,7 +211,7 @@ public class BaseClassTests extends ScriptTestCase {
         }
     }
     public void testDefaultMethods() {
-        Compiler compiler = new Compiler(DefaultMethods.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(DefaultMethods.class, Definition.DEFINITION);
         int rando = randomInt();
         assertEquals(rando, ((DefaultMethods)scriptEngine.compile(compiler, null, "a", emptyMap())).execute(rando, 0, 0, 0));
         assertEquals(rando, ((DefaultMethods)scriptEngine.compile(compiler, null, "a", emptyMap())).executeWithASingleOne(rando, 0, 0));
@@ -225,7 +225,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract void execute(Map<String, Object> map);
     }
     public void testReturnsVoid() {
-        Compiler compiler = new Compiler(ReturnsVoid.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(ReturnsVoid.class, Definition.DEFINITION);
         Map<String, Object> map = new HashMap<>();
         ((ReturnsVoid)scriptEngine.compile(compiler, null, "map.a = 'foo'", emptyMap())).execute(map);
         assertEquals(singletonMap("a", "foo"), map);
@@ -244,7 +244,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract boolean execute();
     }
     public void testReturnsPrimitiveBoolean() {
-        Compiler compiler = new Compiler(ReturnsPrimitiveBoolean.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(ReturnsPrimitiveBoolean.class, Definition.DEFINITION);
 
         assertEquals(true, ((ReturnsPrimitiveBoolean)scriptEngine.compile(compiler, null, "true", emptyMap())).execute());
         assertEquals(false, ((ReturnsPrimitiveBoolean)scriptEngine.compile(compiler, null, "false", emptyMap())).execute());
@@ -286,7 +286,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract int execute();
     }
     public void testReturnsPrimitiveInt() {
-        Compiler compiler = new Compiler(ReturnsPrimitiveInt.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(ReturnsPrimitiveInt.class, Definition.DEFINITION);
 
         assertEquals(1, ((ReturnsPrimitiveInt)scriptEngine.compile(compiler, null, "1", emptyMap())).execute());
         assertEquals(1, ((ReturnsPrimitiveInt)scriptEngine.compile(compiler, null, "(int) 1L", emptyMap())).execute());
@@ -328,7 +328,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract float execute();
     }
     public void testReturnsPrimitiveFloat() {
-        Compiler compiler = new Compiler(ReturnsPrimitiveFloat.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(ReturnsPrimitiveFloat.class, Definition.DEFINITION);
 
         assertEquals(1.1f, ((ReturnsPrimitiveFloat)scriptEngine.compile(compiler, null, "1.1f", emptyMap())).execute(), 0);
         assertEquals(1.1f, ((ReturnsPrimitiveFloat)scriptEngine.compile(compiler, null, "(float) 1.1d", emptyMap())).execute(), 0);
@@ -359,7 +359,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract double execute();
     }
     public void testReturnsPrimitiveDouble() {
-        Compiler compiler = new Compiler(ReturnsPrimitiveDouble.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(ReturnsPrimitiveDouble.class, Definition.DEFINITION);
 
         assertEquals(1.0, ((ReturnsPrimitiveDouble)scriptEngine.compile(compiler, null, "1", emptyMap())).execute(), 0);
         assertEquals(1.0, ((ReturnsPrimitiveDouble)scriptEngine.compile(compiler, null, "1L", emptyMap())).execute(), 0);
@@ -393,7 +393,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract Object execute(String foo);
     }
     public void testNoArgumentsConstant() {
-        Compiler compiler = new Compiler(NoArgumentsConstant.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(NoArgumentsConstant.class, Definition.DEFINITION);
         Exception e = expectScriptThrows(IllegalArgumentException.class, false, () ->
             scriptEngine.compile(compiler, null, "1", emptyMap()));
         assertThat(e.getMessage(), startsWith(
@@ -406,7 +406,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract Object execute(String foo);
     }
     public void testWrongArgumentsConstant() {
-        Compiler compiler = new Compiler(WrongArgumentsConstant.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(WrongArgumentsConstant.class, Definition.DEFINITION);
         Exception e = expectScriptThrows(IllegalArgumentException.class, false, () ->
             scriptEngine.compile(compiler, null, "1", emptyMap()));
         assertThat(e.getMessage(), startsWith(
@@ -419,7 +419,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract Object execute(String foo);
     }
     public void testWrongLengthOfArgumentConstant() {
-        Compiler compiler = new Compiler(WrongLengthOfArgumentConstant.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(WrongLengthOfArgumentConstant.class, Definition.DEFINITION);
         Exception e = expectScriptThrows(IllegalArgumentException.class, false, () ->
             scriptEngine.compile(compiler, null, "1", emptyMap()));
         assertThat(e.getMessage(), startsWith("[" + WrongLengthOfArgumentConstant.class.getName() + "#ARGUMENTS] has length [2] but ["
@@ -431,7 +431,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract Object execute(UnknownArgType foo);
     }
     public void testUnknownArgType() {
-        Compiler compiler = new Compiler(UnknownArgType.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(UnknownArgType.class, Definition.DEFINITION);
         Exception e = expectScriptThrows(IllegalArgumentException.class, false, () ->
             scriptEngine.compile(compiler, null, "1", emptyMap()));
         assertEquals("[foo] is of unknown type [" + UnknownArgType.class.getName() + ". Painless interfaces can only accept arguments "
@@ -443,7 +443,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract UnknownReturnType execute(String foo);
     }
     public void testUnknownReturnType() {
-        Compiler compiler = new Compiler(UnknownReturnType.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(UnknownReturnType.class, Definition.DEFINITION);
         Exception e = expectScriptThrows(IllegalArgumentException.class, false, () ->
             scriptEngine.compile(compiler, null, "1", emptyMap()));
         assertEquals("Painless can only implement execute methods returning a whitelisted type but [" + UnknownReturnType.class.getName()
@@ -455,7 +455,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract Object execute(UnknownArgTypeInArray[] foo);
     }
     public void testUnknownArgTypeInArray() {
-        Compiler compiler = new Compiler(UnknownArgTypeInArray.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(UnknownArgTypeInArray.class, Definition.DEFINITION);
         Exception e = expectScriptThrows(IllegalArgumentException.class, false, () ->
             scriptEngine.compile(compiler, null, "1", emptyMap()));
         assertEquals("[foo] is of unknown type [" + UnknownArgTypeInArray.class.getName() + ". Painless interfaces can only accept "
@@ -467,7 +467,7 @@ public class BaseClassTests extends ScriptTestCase {
         public abstract Object execute(boolean foo);
     }
     public void testTwoExecuteMethods() {
-        Compiler compiler = new Compiler(TwoExecuteMethods.class, Definition.BUILTINS);
+        Compiler compiler = new Compiler(TwoExecuteMethods.class, Definition.DEFINITION);
         Exception e = expectScriptThrows(IllegalArgumentException.class, false, () ->
             scriptEngine.compile(compiler, null, "null", emptyMap()));
         assertEquals("Painless can only implement interfaces that have a single method named [execute] but ["

+ 1 - 1
modules/lang-painless/src/test/java/org/elasticsearch/painless/DebugTests.java

@@ -34,7 +34,7 @@ import static org.hamcrest.Matchers.hasKey;
 import static org.hamcrest.Matchers.not;
 
 public class DebugTests extends ScriptTestCase {
-    private final Definition definition = Definition.BUILTINS;
+    private final Definition definition = Definition.DEFINITION;
 
     public void testExplain() {
         // Debug.explain can explain an object

+ 1 - 1
modules/lang-painless/src/test/java/org/elasticsearch/painless/Debugger.java

@@ -39,7 +39,7 @@ final class Debugger {
         PrintWriter outputWriter = new PrintWriter(output);
         Textifier textifier = new Textifier();
         try {
-            new Compiler(iface, Definition.BUILTINS).compile("<debugging>", source, settings, textifier);
+            new Compiler(iface, Definition.DEFINITION).compile("<debugging>", source, settings, textifier);
         } catch (Exception e) {
             textifier.print(outputWriter);
             e.addSuppressed(new Exception("current bytecode: \n" + output));

+ 32 - 32
modules/lang-painless/src/test/java/org/elasticsearch/painless/DefBootstrapTests.java

@@ -30,14 +30,14 @@ import java.util.HashMap;
 import org.elasticsearch.test.ESTestCase;
 
 public class DefBootstrapTests extends ESTestCase {
-    private final Definition definition = Definition.BUILTINS;
-    
+    private final Definition definition = Definition.DEFINITION;
+
     /** calls toString() on integers, twice */
     public void testOneType() throws Throwable {
         CallSite site = DefBootstrap.bootstrap(definition,
-                                               MethodHandles.publicLookup(), 
-                                               "toString", 
-                                               MethodType.methodType(String.class, Object.class), 
+                                               MethodHandles.publicLookup(),
+                                               "toString",
+                                               MethodType.methodType(String.class, Object.class),
                                                0,
                                                DefBootstrap.METHOD_CALL,
                                                "");
@@ -52,12 +52,12 @@ public class DefBootstrapTests extends ESTestCase {
         assertEquals("6", (String)handle.invokeExact((Object)6));
         assertDepthEquals(site, 1);
     }
-    
+
     public void testTwoTypes() throws Throwable {
         CallSite site = DefBootstrap.bootstrap(definition,
-                                               MethodHandles.publicLookup(), 
-                                               "toString", 
-                                               MethodType.methodType(String.class, Object.class), 
+                                               MethodHandles.publicLookup(),
+                                               "toString",
+                                               MethodType.methodType(String.class, Object.class),
                                                0,
                                                DefBootstrap.METHOD_CALL,
                                                "");
@@ -75,14 +75,14 @@ public class DefBootstrapTests extends ESTestCase {
         assertEquals("2.5", (String)handle.invokeExact((Object)2.5f));
         assertDepthEquals(site, 2);
     }
-    
+
     public void testTooManyTypes() throws Throwable {
         // if this changes, test must be rewritten
         assertEquals(5, DefBootstrap.PIC.MAX_DEPTH);
         CallSite site = DefBootstrap.bootstrap(definition,
-                                               MethodHandles.publicLookup(), 
-                                               "toString", 
-                                               MethodType.methodType(String.class, Object.class), 
+                                               MethodHandles.publicLookup(),
+                                               "toString",
+                                               MethodType.methodType(String.class, Object.class),
                                                0,
                                                DefBootstrap.METHOD_CALL,
                                                "");
@@ -102,13 +102,13 @@ public class DefBootstrapTests extends ESTestCase {
         assertEquals("c", (String)handle.invokeExact((Object)'c'));
         assertDepthEquals(site, 5);
     }
-    
+
     /** test that we revert to the megamorphic classvalue cache and that it works as expected */
     public void testMegamorphic() throws Throwable {
-        DefBootstrap.PIC site = (DefBootstrap.PIC) DefBootstrap.bootstrap(definition, 
-                                                                          MethodHandles.publicLookup(), 
-                                                                          "size", 
-                                                                          MethodType.methodType(int.class, Object.class), 
+        DefBootstrap.PIC site = (DefBootstrap.PIC) DefBootstrap.bootstrap(definition,
+                                                                          MethodHandles.publicLookup(),
+                                                                          "size",
+                                                                          MethodType.methodType(int.class, Object.class),
                                                                           0,
                                                                           DefBootstrap.METHOD_CALL,
                                                                           "");
@@ -118,12 +118,12 @@ public class DefBootstrapTests extends ESTestCase {
         assertEquals(1, (int)handle.invokeExact((Object) Collections.singletonMap("a", "b")));
         assertEquals(3, (int)handle.invokeExact((Object) Arrays.asList("x", "y", "z")));
         assertEquals(2, (int)handle.invokeExact((Object) Arrays.asList("u", "v")));
-        
+
         final HashMap<String,String> map = new HashMap<>();
         map.put("x", "y");
         map.put("a", "b");
         assertEquals(2, (int)handle.invokeExact((Object) map));
-        
+
         final IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> {
             Integer.toString((int)handle.invokeExact(new Object()));
         });
@@ -133,12 +133,12 @@ public class DefBootstrapTests extends ESTestCase {
                    e.getClassName().startsWith("org.elasticsearch.painless.DefBootstrap$PIC$");
         }));
     }
-    
+
     // test operators with null guards
 
     public void testNullGuardAdd() throws Throwable {
         DefBootstrap.MIC site = (DefBootstrap.MIC) DefBootstrap.bootstrap(definition,
-                                                                          MethodHandles.publicLookup(), 
+                                                                          MethodHandles.publicLookup(),
                                                                           "add",
                                                                           MethodType.methodType(Object.class, Object.class, Object.class),
                                                                           0,
@@ -147,7 +147,7 @@ public class DefBootstrapTests extends ESTestCase {
         MethodHandle handle = site.dynamicInvoker();
         assertEquals("nulltest", (Object)handle.invokeExact((Object)null, (Object)"test"));
     }
-    
+
     public void testNullGuardAddWhenCached() throws Throwable {
         DefBootstrap.MIC site = (DefBootstrap.MIC) DefBootstrap.bootstrap(definition,
                                                                           MethodHandles.publicLookup(),
@@ -160,11 +160,11 @@ public class DefBootstrapTests extends ESTestCase {
         assertEquals(2, (Object)handle.invokeExact((Object)1, (Object)1));
         assertEquals("nulltest", (Object)handle.invokeExact((Object)null, (Object)"test"));
     }
-    
+
     public void testNullGuardEq() throws Throwable {
         DefBootstrap.MIC site = (DefBootstrap.MIC) DefBootstrap.bootstrap(definition,
-                                                                          MethodHandles.publicLookup(), 
-                                                                          "eq", 
+                                                                          MethodHandles.publicLookup(),
+                                                                          "eq",
                                                                           MethodType.methodType(boolean.class, Object.class, Object.class),
                                                                           0,
                                                                           DefBootstrap.BINARY_OPERATOR,
@@ -173,7 +173,7 @@ public class DefBootstrapTests extends ESTestCase {
         assertFalse((boolean) handle.invokeExact((Object)null, (Object)"test"));
         assertTrue((boolean) handle.invokeExact((Object)null, (Object)null));
     }
-    
+
     public void testNullGuardEqWhenCached() throws Throwable {
         DefBootstrap.MIC site = (DefBootstrap.MIC) DefBootstrap.bootstrap(definition,
                                                                           MethodHandles.publicLookup(),
@@ -187,14 +187,14 @@ public class DefBootstrapTests extends ESTestCase {
         assertFalse((boolean) handle.invokeExact((Object)null, (Object)"test"));
         assertTrue((boolean) handle.invokeExact((Object)null, (Object)null));
     }
-    
+
     // make sure these operators work without null guards too
     // for example, nulls are only legal for + if the other parameter is a String,
     // and can be disabled in some circumstances.
-    
+
     public void testNoNullGuardAdd() throws Throwable {
         DefBootstrap.MIC site = (DefBootstrap.MIC) DefBootstrap.bootstrap(definition,
-                                                                          MethodHandles.publicLookup(), 
+                                                                          MethodHandles.publicLookup(),
                                                                           "add",
                                                                           MethodType.methodType(Object.class, int.class, Object.class),
                                                                           0,
@@ -205,7 +205,7 @@ public class DefBootstrapTests extends ESTestCase {
             assertNotNull((Object)handle.invokeExact(5, (Object)null));
         });
     }
-    
+
     public void testNoNullGuardAddWhenCached() throws Throwable {
         DefBootstrap.MIC site = (DefBootstrap.MIC) DefBootstrap.bootstrap(definition,
                                                                           MethodHandles.publicLookup(),
@@ -220,7 +220,7 @@ public class DefBootstrapTests extends ESTestCase {
             assertNotNull((Object)handle.invokeExact(5, (Object)null));
         });
     }
-    
+
     static void assertDepthEquals(CallSite site, int expected) {
         DefBootstrap.PIC dsite = (DefBootstrap.PIC) site;
         assertEquals(expected, dsite.depth);

+ 11 - 11
modules/lang-painless/src/test/java/org/elasticsearch/painless/OrTests.java

@@ -52,7 +52,7 @@ public class OrTests extends ScriptTestCase {
         assertEquals(5L | -12L, exec("return 5L | -12L;"));
         assertEquals(7L | 15L | 3L, exec("return 7L | 15L | 3L;"));
     }
-    
+
     public void testIllegal() throws Exception {
         expectScriptThrows(ClassCastException.class, () -> {
             exec("float x = (float)4; int y = 1; return x | y");
@@ -61,7 +61,7 @@ public class OrTests extends ScriptTestCase {
             exec("double x = (double)4; int y = 1; return x | y");
         });
     }
-    
+
     public void testDef() {
         expectScriptThrows(ClassCastException.class, () -> {
             exec("def x = (float)4; def y = (byte)1; return x | y");
@@ -104,13 +104,13 @@ public class OrTests extends ScriptTestCase {
         assertEquals(5, exec("def x = (char)4; def y = (char)1; return x | y"));
         assertEquals(5, exec("def x = (int)4; def y = (int)1; return x | y"));
         assertEquals(5L, exec("def x = (long)4; def y = (long)1; return x | y"));
-        
+
         assertEquals(true,  exec("def x = true;  def y = true; return x | y"));
         assertEquals(true,  exec("def x = true;  def y = false; return x | y"));
         assertEquals(true,  exec("def x = false; def y = true; return x | y"));
         assertEquals(false, exec("def x = false; def y = false; return x | y"));
     }
-    
+
     public void testDefTypedLHS() {
         expectScriptThrows(ClassCastException.class, () -> {
             exec("float x = (float)4; def y = (byte)1; return x | y");
@@ -153,13 +153,13 @@ public class OrTests extends ScriptTestCase {
         assertEquals(5, exec("char x = (char)4; def y = (char)1; return x | y"));
         assertEquals(5, exec("int x = (int)4; def y = (int)1; return x | y"));
         assertEquals(5L, exec("long x = (long)4; def y = (long)1; return x | y"));
-        
+
         assertEquals(true,  exec("boolean x = true;  def y = true; return x | y"));
         assertEquals(true,  exec("boolean x = true;  def y = false; return x | y"));
         assertEquals(true,  exec("boolean x = false; def y = true; return x | y"));
         assertEquals(false, exec("boolean x = false; def y = false; return x | y"));
     }
-    
+
     public void testDefTypedRHS() {
         expectScriptThrows(ClassCastException.class, () -> {
             exec("def x = (float)4; byte y = (byte)1; return x | y");
@@ -202,13 +202,13 @@ public class OrTests extends ScriptTestCase {
         assertEquals(5, exec("def x = (char)4; char y = (char)1; return x | y"));
         assertEquals(5, exec("def x = (int)4; int y = (int)1; return x | y"));
         assertEquals(5L, exec("def x = (long)4; long y = (long)1; return x | y"));
-        
+
         assertEquals(true,  exec("def x = true;  boolean y = true; return x | y"));
         assertEquals(true,  exec("def x = true;  boolean y = false; return x | y"));
         assertEquals(true,  exec("def x = false; boolean y = true; return x | y"));
         assertEquals(false, exec("def x = false; boolean y = false; return x | y"));
     }
-    
+
     public void testCompoundAssignment() {
         // boolean
         assertEquals(true, exec("boolean x = true; x |= true; return x;"));
@@ -231,7 +231,7 @@ public class OrTests extends ScriptTestCase {
         // long
         assertEquals((long) (13 | 14), exec("long x = 13L; x |= 14; return x;"));
     }
-    
+
     public void testBogusCompoundAssignment() {
         expectScriptThrows(ClassCastException.class, () -> {
             exec("float x = 4; int y = 1; x |= y");
@@ -246,7 +246,7 @@ public class OrTests extends ScriptTestCase {
             exec("int x = 4; double y = 1; x |= y");
         });
     }
-    
+
     public void testDefCompoundAssignment() {
         // boolean
         assertEquals(true, exec("def x = true; x |= true; return x;"));
@@ -269,7 +269,7 @@ public class OrTests extends ScriptTestCase {
         // long
         assertEquals((long) (13 | 14), exec("def x = 13L; x |= 14; return x;"));
     }
-    
+
     public void testDefBogusCompoundAssignment() {
         expectScriptThrows(ClassCastException.class, () -> {
             exec("def x = 4F; int y = 1; x |= y");

+ 2 - 1
modules/lang-painless/src/test/java/org/elasticsearch/painless/PainlessDocGenerator.java

@@ -44,6 +44,7 @@ import java.util.function.Consumer;
 
 import static java.util.Comparator.comparing;
 import static java.util.stream.Collectors.toList;
+import static org.elasticsearch.painless.Definition.DEFINITION;
 
 /**
  * Generates an API reference from the method and type whitelists in {@link Definition}.
@@ -67,7 +68,7 @@ public class PainlessDocGenerator {
                 Files.newOutputStream(indexPath, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE),
                 false, StandardCharsets.UTF_8.name())) {
             emitGeneratedWarning(indexStream);
-            List<Type> types = Definition.allSimpleTypes().stream().sorted(comparing(t -> t.name)).collect(toList());
+            List<Type> types = DEFINITION.allSimpleTypes().stream().sorted(comparing(t -> t.name)).collect(toList());
             for (Type type : types) {
                 if (type.clazz.isPrimitive()) {
                     // Primitives don't have methods to reference

+ 1 - 1
modules/lang-painless/src/test/java/org/elasticsearch/painless/ScriptTestCase.java

@@ -91,7 +91,7 @@ public abstract class ScriptTestCase extends ESTestCase {
     public Object exec(String script, Map<String, Object> vars, Map<String,String> compileParams, Scorer scorer, boolean picky) {
         // test for ambiguity errors before running the actual script if picky is true
         if (picky) {
-            Definition definition = Definition.BUILTINS;
+            Definition definition = Definition.DEFINITION;
             ScriptClassInfo scriptClassInfo = new ScriptClassInfo(definition, GenericElasticsearchScript.class);
             CompilerSettings pickySettings = new CompilerSettings();
             pickySettings.setPicky(true);

+ 6 - 6
modules/lang-painless/src/test/java/org/elasticsearch/painless/node/NodeToStringTests.java

@@ -48,7 +48,7 @@ import static org.elasticsearch.painless.node.SSource.MainMethodReserved;
  * Tests {@link Object#toString} implementations on all extensions of {@link ANode}.
  */
 public class NodeToStringTests extends ESTestCase {
-    private final Definition definition = Definition.BUILTINS;
+    private final Definition definition = Definition.DEFINITION;
 
     public void testEAssignment() {
         assertToString(
@@ -161,12 +161,12 @@ public class NodeToStringTests extends ESTestCase {
     public void testECast() {
         Location l = new Location(getTestName(), 0);
         AExpression child = new EConstant(l, "test");
-        Cast cast = new Cast(Definition.STRING_TYPE, Definition.INT_OBJ_TYPE, true);
+        Cast cast = new Cast(Definition.DEFINITION.StringType, Definition.DEFINITION.IntegerType, true);
         assertEquals("(ECast Integer (EConstant String 'test'))", new ECast(l, child, cast).toString());
 
         l = new Location(getTestName(), 1);
         child = new EBinary(l, Operation.ADD, new EConstant(l, "test"), new EConstant(l, 12));
-        cast = new Cast(Definition.INT_OBJ_TYPE, Definition.BOOLEAN_OBJ_TYPE, true);
+        cast = new Cast(Definition.DEFINITION.IntegerType, Definition.DEFINITION.BooleanType, true);
         assertEquals("(ECast Boolean (EBinary (EConstant String 'test') + (EConstant Integer 12)))", new ECast(l, child, cast).toString());
     }
 
@@ -395,7 +395,7 @@ public class NodeToStringTests extends ESTestCase {
 
     public void testPSubBrace() {
         Location l = new Location(getTestName(), 0);
-        PSubBrace node = new PSubBrace(l, Definition.INT_TYPE, new ENumeric(l, "1", 10));
+        PSubBrace node = new PSubBrace(l, Definition.DEFINITION.intType, new ENumeric(l, "1", 10));
         node.prefix = new EVariable(l, "a");
         assertEquals("(PSubBrace (EVariable a) (ENumeric 1))", node.toString());
     }
@@ -761,7 +761,7 @@ public class NodeToStringTests extends ESTestCase {
 
     public void testSSubEachArray() {
         Location l = new Location(getTestName(), 0);
-        Variable v = new Variable(l, "test", Definition.INT_TYPE, 5, false);
+        Variable v = new Variable(l, "test", Definition.DEFINITION.intType, 5, false);
         AExpression e = new ENewArray(l, "int", Arrays.asList(new EConstant(l, 1), new EConstant(l, 2), new EConstant(l, 3)), true);
         SBlock b = new SBlock(l, singletonList(new SReturn(l, new EConstant(l, 5))));
         SSubEachArray node = new SSubEachArray(l, v, e, b);
@@ -773,7 +773,7 @@ public class NodeToStringTests extends ESTestCase {
 
     public void testSSubEachIterable() {
         Location l = new Location(getTestName(), 0);
-        Variable v = new Variable(l, "test", Definition.INT_TYPE, 5, false);
+        Variable v = new Variable(l, "test", Definition.DEFINITION.intType, 5, false);
         AExpression e = new EListInit(l, Arrays.asList(new EConstant(l, 1), new EConstant(l, 2), new EConstant(l, 3)));
         SBlock b = new SBlock(l, singletonList(new SReturn(l, new EConstant(l, 5))));
         SSubEachIterable node = new SSubEachIterable(l, v, e, b);