From 915ab16176b95524968b07a2faa5b217a03cfcaa Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Thu, 19 May 2016 09:29:48 -0400 Subject: [PATCH 01/22] First steps at whitelist cleanup --- .../painless/AnalyzerCaster.java | 96 +- .../elasticsearch/painless/Definition.java | 1267 +++-------------- .../elasticsearch/painless/MethodWriter.java | 166 +-- .../painless/PainlessPlugin.java | 11 + .../painless/PainlessScriptEngineService.java | 2 - .../org/elasticsearch/painless/Variables.java | 18 +- .../elasticsearch/painless/node/EBinary.java | 6 +- .../elasticsearch/painless/node/EBool.java | 6 +- .../elasticsearch/painless/node/EBoolean.java | 2 +- .../elasticsearch/painless/node/EChain.java | 6 +- .../elasticsearch/painless/node/EComp.java | 32 +- .../painless/node/EConditional.java | 2 +- .../painless/node/EConstant.java | 18 +- .../elasticsearch/painless/node/EDecimal.java | 4 +- .../elasticsearch/painless/node/ENull.java | 2 +- .../elasticsearch/painless/node/ENumeric.java | 14 +- .../elasticsearch/painless/node/EUnary.java | 12 +- .../painless/node/LArrayLength.java | 2 +- .../elasticsearch/painless/node/LBrace.java | 2 +- .../painless/node/LDefArray.java | 6 +- .../elasticsearch/painless/node/LDefCall.java | 4 +- .../painless/node/LDefField.java | 6 +- .../painless/node/LListShortcut.java | 2 +- .../painless/node/LNewArray.java | 2 +- .../elasticsearch/painless/node/LString.java | 2 +- .../org/elasticsearch/painless/node/SDo.java | 2 +- .../painless/node/SExpression.java | 2 +- .../org/elasticsearch/painless/node/SFor.java | 2 +- .../elasticsearch/painless/node/SIfElse.java | 2 +- .../elasticsearch/painless/node/SReturn.java | 2 +- .../elasticsearch/painless/node/SThrow.java | 2 +- .../elasticsearch/painless/node/SWhile.java | 2 +- .../org/elasticsearch/painless/definition.txt | 529 +++++++ .../elasticsearch/painless/BasicAPITests.java | 14 +- .../painless/BasicStatementTests.java | 8 +- .../painless/NoSemiColonTests.java | 8 +- 36 files changed, 997 insertions(+), 1266 deletions(-) create mode 100644 modules/lang-painless/src/main/resources/org/elasticsearch/painless/definition.txt diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java index 3228ff47e92..d6f099e47f9 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java @@ -119,18 +119,18 @@ public final class AnalyzerCaster { final Sort sort = from.sort; if (sort == Sort.DEF) { - return definition.defType; + return definition.getType("def"); } else if ((sort == Sort.DOUBLE || sort == Sort.DOUBLE_OBJ) && decimal) { - return primitive ? definition.doubleType : definition.doubleobjType; + return primitive ? definition.getType("double") : definition.getType("Double"); } else if ((sort == Sort.FLOAT || sort == Sort.FLOAT_OBJ) && decimal) { - return primitive ? definition.floatType : definition.floatobjType; + return primitive ? definition.getType("float") : definition.getType("Float"); } else if (sort == Sort.LONG || sort == Sort.LONG_OBJ) { - return primitive ? definition.longType : definition.longobjType; + return primitive ? definition.getType("long") : definition.getType("Long"); } else if (sort == Sort.INT || sort == Sort.INT_OBJ || sort == Sort.CHAR || sort == Sort.CHAR_OBJ || sort == Sort.SHORT || sort == Sort.SHORT_OBJ || sort == Sort.BYTE || sort == Sort.BYTE_OBJ) { - return primitive ? definition.intType : definition.intobjType; + return primitive ? definition.getType("int") : definition.getType("Integer"); } return null; @@ -142,21 +142,21 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.DEF || sort1 == Sort.DEF) { - return definition.defType; + return definition.getType("def"); } if (decimal) { if (sort0 == Sort.DOUBLE || sort0 == Sort.DOUBLE_OBJ || sort1 == Sort.DOUBLE || sort1 == Sort.DOUBLE_OBJ) { - return primitive ? definition.doubleType : definition.doubleobjType; + return primitive ? definition.getType("double") : definition.getType("Double"); } else if (sort0 == Sort.FLOAT || sort0 == Sort.FLOAT_OBJ || sort1 == Sort.FLOAT || sort1 == Sort.FLOAT_OBJ) { - return primitive ? definition.floatType : definition.floatobjType; + return primitive ? definition.getType("float") : definition.getType("Float"); } } if (sort0 == Sort.LONG || sort0 == Sort.LONG_OBJ || sort1 == Sort.LONG || sort1 == Sort.LONG_OBJ) { - return primitive ? definition.longType : definition.longobjType; + return primitive ? definition.getType("long") : definition.getType("Long"); } else if (sort0 == Sort.INT || sort0 == Sort.INT_OBJ || sort1 == Sort.INT || sort1 == Sort.INT_OBJ || sort0 == Sort.CHAR || sort0 == Sort.CHAR_OBJ || @@ -165,7 +165,7 @@ public final class AnalyzerCaster { sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ || sort0 == Sort.BYTE || sort0 == Sort.BYTE_OBJ || sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { - return primitive ? definition.intType : definition.intobjType; + return primitive ? definition.getType("int") : definition.getType("Integer"); } return null; @@ -176,7 +176,7 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.STRING || sort1 == Sort.STRING) { - return definition.stringType; + return definition.getType("String"); } return promoteNumeric(definition, from0, from1, true, true); @@ -187,7 +187,7 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0.bool || sort1.bool) { - return definition.booleanType; + return definition.getType("boolean"); } return promoteNumeric(definition, from0, from1, false, true); @@ -198,20 +198,20 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.DEF || sort1 == Sort.DEF) { - return definition.defType; + return definition.getType("def"); } final boolean primitive = sort0.primitive && sort1.primitive; if (sort0.bool && sort1.bool) { - return primitive ? definition.booleanType : definition.booleanobjType; + return primitive ? definition.getType("boolean") : definition.getType("Boolean"); } if (sort0.numeric && sort1.numeric) { return promoteNumeric(definition, from0, from1, true, primitive); } - return definition.objectType; + return definition.getType("Object"); } public static Type promoteReference(final Definition definition, final Type from0, final Type from1) { @@ -219,12 +219,12 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.DEF || sort1 == Sort.DEF) { - return definition.defType; + return definition.getType("def"); } if (sort0.primitive && sort1.primitive) { if (sort0.bool && sort1.bool) { - return definition.booleanType; + return definition.getType("boolean"); } if (sort0.numeric && sort1.numeric) { @@ -232,7 +232,7 @@ public final class AnalyzerCaster { } } - return definition.objectType; + return definition.getType("Object"); } public static Type promoteConditional(final Definition definition, @@ -245,48 +245,48 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.DEF || sort1 == Sort.DEF) { - return definition.defType; + return definition.getType("def"); } final boolean primitive = sort0.primitive && sort1.primitive; if (sort0.bool && sort1.bool) { - return primitive ? definition.booleanType : definition.booleanobjType; + return primitive ? definition.getType("boolean") : definition.getType("Boolean"); } if (sort0.numeric && sort1.numeric) { if (sort0 == Sort.DOUBLE || sort0 == Sort.DOUBLE_OBJ || sort1 == Sort.DOUBLE || sort1 == Sort.DOUBLE_OBJ) { - return primitive ? definition.doubleType : definition.doubleobjType; + return primitive ? definition.getType("double") : definition.getType("Double"); } else if (sort0 == Sort.FLOAT || sort0 == Sort.FLOAT_OBJ || sort1 == Sort.FLOAT || sort1 == Sort.FLOAT_OBJ) { - return primitive ? definition.floatType : definition.floatobjType; + return primitive ? definition.getType("float") : definition.getType("Float"); } else if (sort0 == Sort.LONG || sort0 == Sort.LONG_OBJ || sort1 == Sort.LONG || sort1 == Sort.LONG_OBJ) { - return sort0.primitive && sort1.primitive ? definition.longType : definition.longobjType; + return sort0.primitive && sort1.primitive ? definition.getType("long") : definition.getType("Long"); } else { if (sort0 == Sort.BYTE || sort0 == Sort.BYTE_OBJ) { if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { - return primitive ? definition.byteType : definition.byteobjType; + return primitive ? definition.getType("byte") : definition.getType("Byte"); } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { if (const1 != null) { final short constant = (short)const1; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? definition.byteType : definition.byteobjType; + return primitive ? definition.getType("byte") : definition.getType("Byte"); } } - return primitive ? definition.shortType : definition.shortobjType; + return primitive ? definition.getType("short") : definition.getType("Short"); } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { - return primitive ? definition.intType : definition.intobjType; + return primitive ? definition.getType("int") : definition.getType("Integer"); } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { if (const1 != null) { final int constant = (int)const1; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? definition.byteType : definition.byteobjType; + return primitive ? definition.getType("byte") : definition.getType("Byte"); } } - return primitive ? definition.intType : definition.intobjType; + return primitive ? definition.getType("int") : definition.getType("Integer"); } } else if (sort0 == Sort.SHORT || sort0 == Sort.SHORT_OBJ) { if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { @@ -294,43 +294,43 @@ public final class AnalyzerCaster { final short constant = (short)const0; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? definition.byteType : definition.byteobjType; + return primitive ? definition.getType("byte") : definition.getType("Byte"); } } - return primitive ? definition.shortType : definition.shortobjType; + return primitive ? definition.getType("short") : definition.getType("Short"); } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { - return primitive ? definition.shortType : definition.shortobjType; + return primitive ? definition.getType("short") : definition.getType("Short"); } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { - return primitive ? definition.intType : definition.intobjType; + return primitive ? definition.getType("int") : definition.getType("Integer"); } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { if (const1 != null) { final int constant = (int)const1; if (constant <= Short.MAX_VALUE && constant >= Short.MIN_VALUE) { - return primitive ? definition.shortType : definition.shortobjType; + return primitive ? definition.getType("short") : definition.getType("Short"); } } - return primitive ? definition.intType : definition.intobjType; + return primitive ? definition.getType("int") : definition.getType("Integer"); } } else if (sort0 == Sort.CHAR || sort0 == Sort.CHAR_OBJ) { if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { - return primitive ? definition.intType : definition.intobjType; + return primitive ? definition.getType("int") : definition.getType("Integer"); } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { - return primitive ? definition.intType : definition.intobjType; + return primitive ? definition.getType("int") : definition.getType("Integer"); } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { - return primitive ? definition.charType : definition.charobjType; + return primitive ? definition.getType("char") : definition.getType("Character"); } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { if (const1 != null) { final int constant = (int)const1; if (constant <= Character.MAX_VALUE && constant >= Character.MIN_VALUE) { - return primitive ? definition.byteType : definition.byteobjType; + return primitive ? definition.getType("byte") : definition.getType("Byte"); } } - return primitive ? definition.intType : definition.intobjType; + return primitive ? definition.getType("int") : definition.getType("Integer"); } } else if (sort0 == Sort.INT || sort0 == Sort.INT_OBJ) { if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { @@ -338,33 +338,33 @@ public final class AnalyzerCaster { final int constant = (int)const0; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? definition.byteType : definition.byteobjType; + return primitive ? definition.getType("byte") : definition.getType("Byte"); } } - return primitive ? definition.intType : definition.intobjType; + return primitive ? definition.getType("int") : definition.getType("Integer"); } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { if (const0 != null) { final int constant = (int)const0; if (constant <= Short.MAX_VALUE && constant >= Short.MIN_VALUE) { - return primitive ? definition.byteType : definition.byteobjType; + return primitive ? definition.getType("byte") : definition.getType("Byte"); } } - return primitive ? definition.intType : definition.intobjType; + return primitive ? definition.getType("int") : definition.getType("Integer"); } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { if (const0 != null) { final int constant = (int)const0; if (constant <= Character.MAX_VALUE && constant >= Character.MIN_VALUE) { - return primitive ? definition.byteType : definition.byteobjType; + return primitive ? definition.getType("byte") : definition.getType("Byte"); } } - return primitive ? definition.intType : definition.intobjType; + return primitive ? definition.getType("int") : definition.getType("Integer"); } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { - return primitive ? definition.intType : definition.intobjType; + return primitive ? definition.getType("int") : definition.getType("Integer"); } } } @@ -374,7 +374,7 @@ public final class AnalyzerCaster { // to calculate the highest upper bound for the two types and return that. // However, for now we just return objectType that may require an extra cast. - return definition.objectType; + return definition.getType("Object"); } private AnalyzerCaster() {} diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java index f44db5cb504..68fc3a32262 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java @@ -19,22 +19,18 @@ package org.elasticsearch.painless; -import org.elasticsearch.common.geo.GeoPoint; -import org.elasticsearch.index.fielddata.ScriptDocValues; - +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.LineNumberReader; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; -import java.util.ArrayList; +import java.nio.charset.StandardCharsets; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Set; /** * The entire API for Painless. Also used as a whitelist for checking for legal @@ -373,176 +369,30 @@ public final class Definition { } } - public final Map structsMap; - public final Map transformsMap; - public final Map, RuntimeClass> runtimeMap; - - public final Type voidType; - public final Type booleanType; - public final Type byteType; - public final Type shortType; - public final Type charType; - public final Type intType; - public final Type longType; - public final Type floatType; - public final Type doubleType; - - public final Type voidobjType; - public final Type booleanobjType; - public final Type byteobjType; - public final Type shortobjType; - public final Type charobjType; - public final Type intobjType; - public final Type longobjType; - public final Type floatobjType; - public final Type doubleobjType; - - public final Type objectType; - public final Type defType; - public final Type numberType; - public final Type charseqType; - public final Type stringType; - public final Type mathType; - public final Type utilityType; - public final Type defobjType; - - public final Type itrType; - public final Type oitrType; - public final Type sitrType; - - public final Type collectionType; - public final Type ocollectionType; - public final Type scollectionType; - - public final Type listType; - public final Type arraylistType; - public final Type olistType; - public final Type oarraylistType; - public final Type slistType; - public final Type sarraylistType; - - public final Type setType; - public final Type hashsetType; - public final Type osetType; - public final Type ohashsetType; - public final Type ssetType; - public final Type shashsetType; - - public final Type mapType; - public final Type hashmapType; - public final Type oomapType; - public final Type oohashmapType; - public final Type smapType; - public final Type shashmapType; - public final Type somapType; - public final Type sohashmapType; - - public final Type execType; - - public final Type exceptionType; - public final Type arithexcepType; - public final Type iargexcepType; - public final Type istateexceptType; - public final Type nfexcepType; - - // docvalues accessors - public final Type geoPointType; - public final Type stringsType; - // TODO: add ReadableDateTime? or don't expose the joda stuff? - public final Type longsType; - public final Type doublesType; - public final Type geoPointsType; - - // for testing features not currently "used" by the whitelist (we should not rush the API for that!) - public final Type featureTestType; + final Map transformsMap; + final Map, RuntimeClass> runtimeMap; + private final Map structsMap; + private final Map simpleTypesMap; private Definition() { structsMap = new HashMap<>(); + simpleTypesMap = new HashMap<>(); transformsMap = new HashMap<>(); runtimeMap = new HashMap<>(); - addStructs(); - - voidType = getType("void"); - booleanType = getType("boolean"); - byteType = getType("byte"); - shortType = getType("short"); - charType = getType("char"); - intType = getType("int"); - longType = getType("long"); - floatType = getType("float"); - doubleType = getType("double"); - - voidobjType = getType("Void"); - booleanobjType = getType("Boolean"); - byteobjType = getType("Byte"); - shortobjType = getType("Short"); - charobjType = getType("Character"); - intobjType = getType("Integer"); - longobjType = getType("Long"); - floatobjType = getType("Float"); - doubleobjType = getType("Double"); - - objectType = getType("Object"); - defType = getType("def"); - numberType = getType("Number"); - charseqType = getType("CharSequence"); - stringType = getType("String"); - mathType = getType("Math"); - utilityType = getType("Utility"); - defobjType = getType("Def"); - - itrType = getType("Iterator"); - oitrType = getType("Iterator"); - sitrType = getType("Iterator"); - - collectionType = getType("Collection"); - ocollectionType = getType("Collection"); - scollectionType = getType("Collection"); - - listType = getType("List"); - arraylistType = getType("ArrayList"); - olistType = getType("List"); - oarraylistType = getType("ArrayList"); - slistType = getType("List"); - sarraylistType = getType("ArrayList"); - - setType = getType("Set"); - hashsetType = getType("HashSet"); - osetType = getType("Set"); - ohashsetType = getType("HashSet"); - ssetType = getType("Set"); - shashsetType = getType("HashSet"); - - mapType = getType("Map"); - hashmapType = getType("HashMap"); - oomapType = getType("Map"); - oohashmapType = getType("HashMap"); - smapType = getType("Map"); - shashmapType = getType("HashMap"); - somapType = getType("Map"); - sohashmapType = getType("HashMap"); - - execType = getType("Executable"); - - exceptionType = getType("Exception"); - arithexcepType = getType("ArithmeticException"); - iargexcepType = getType("IllegalArgumentException"); - istateexceptType = getType("IllegalStateException"); - nfexcepType = getType("NumberFormatException"); - - geoPointType = getType("GeoPoint"); - stringsType = getType("Strings"); - longsType = getType("Longs"); - doublesType = getType("Doubles"); - geoPointsType = getType("GeoPoints"); - - featureTestType = getType("FeatureTest"); - + // parse the classes and return hierarchy (map of class name -> superclasses/interfaces) + Map> hierarchy = addStructs(); + // add every method for each class addElements(); - copyStructs(); + // apply hierarchy: this means e.g. copying Object's methods into String (thats how subclasses work) + for (Map.Entry> clazz : hierarchy.entrySet()) { + copyStruct(clazz.getKey(), clazz.getValue()); + } addTransforms(); - addRuntimeClasses(); + // precompute runtime classes + for (Struct struct : structsMap.values()) { + addRuntimeClass(struct); + } } private Definition(final Definition definition) { @@ -555,710 +405,128 @@ public final class Definition { this.structsMap = Collections.unmodifiableMap(structs); this.transformsMap = Collections.unmodifiableMap(definition.transformsMap); this.runtimeMap = Collections.unmodifiableMap(definition.runtimeMap); - - this.voidType = definition.voidType; - this.booleanType = definition.booleanType; - this.byteType = definition.byteType; - this.shortType = definition.shortType; - this.charType = definition.charType; - this.intType = definition.intType; - this.longType = definition.longType; - this.floatType = definition.floatType; - this.doubleType = definition.doubleType; - - this.voidobjType = definition.voidobjType; - this.booleanobjType = definition.booleanobjType; - this.byteobjType = definition.byteobjType; - this.shortobjType = definition.shortobjType; - this.charobjType = definition.charobjType; - this.intobjType = definition.intobjType; - this.longobjType = definition.longobjType; - this.floatobjType = definition.floatobjType; - this.doubleobjType = definition.doubleobjType; - - this.objectType = definition.objectType; - this.defType = definition.defType; - this.numberType = definition.numberType; - this.charseqType = definition.charseqType; - this.stringType = definition.stringType; - this.mathType = definition.mathType; - this.utilityType = definition.utilityType; - this.defobjType = definition.defobjType; - - this.itrType = definition.itrType; - this.oitrType = definition.oitrType; - this.sitrType = definition.sitrType; - - this.collectionType = definition.collectionType; - this.ocollectionType = definition.ocollectionType; - this.scollectionType = definition.scollectionType; - - this.listType = definition.listType; - this.arraylistType = definition.arraylistType; - this.olistType = definition.olistType; - this.oarraylistType = definition.oarraylistType; - this.slistType = definition.slistType; - this.sarraylistType = definition.sarraylistType; - - this.setType = definition.setType; - this.hashsetType = definition.hashsetType; - this.osetType = definition.osetType; - this.ohashsetType = definition.ohashsetType; - this.ssetType = definition.ssetType; - this.shashsetType = definition.shashsetType; - - this.mapType = definition.mapType; - this.hashmapType = definition.hashmapType; - this.oomapType = definition.oomapType; - this.oohashmapType = definition.oohashmapType; - this.smapType = definition.smapType; - this.shashmapType = definition.shashmapType; - this.somapType = definition.somapType; - this.sohashmapType = definition.sohashmapType; - - this.execType = definition.execType; - - this.exceptionType = definition.exceptionType; - this.arithexcepType = definition.arithexcepType; - this.iargexcepType = definition.iargexcepType; - this.istateexceptType = definition.istateexceptType; - this.nfexcepType = definition.nfexcepType; - - this.geoPointType = definition.geoPointType; - this.stringsType = definition.stringsType; - this.longsType = definition.longsType; - this.doublesType = definition.doublesType; - this.geoPointsType = definition.geoPointsType; - - this.featureTestType = definition.featureTestType; + this.simpleTypesMap = Collections.unmodifiableMap(definition.simpleTypesMap); } - private void addStructs() { - addStruct( "void" , void.class ); - addStruct( "boolean" , boolean.class ); - addStruct( "byte" , byte.class ); - addStruct( "short" , short.class ); - addStruct( "char" , char.class ); - addStruct( "int" , int.class ); - addStruct( "long" , long.class ); - addStruct( "float" , float.class ); - addStruct( "double" , double.class ); - - addStruct( "Void" , Void.class ); - addStruct( "Boolean" , Boolean.class ); - addStruct( "Byte" , Byte.class ); - addStruct( "Short" , Short.class ); - addStruct( "Character" , Character.class ); - addStruct( "Integer" , Integer.class ); - addStruct( "Long" , Long.class ); - addStruct( "Float" , Float.class ); - addStruct( "Double" , Double.class ); - - addStruct( "Object" , Object.class ); - addStruct( "def" , Object.class ); - addStruct( "Number" , Number.class ); - addStruct( "CharSequence" , CharSequence.class ); - addStruct( "String" , String.class ); - addStruct( "Math" , Math.class ); - addStruct( "Utility" , Utility.class ); - addStruct( "Def" , Def.class ); - - addStruct( "Iterator" , Iterator.class ); - addStruct( "Iterator" , Iterator.class ); - addStruct( "Iterator" , Iterator.class ); - - addStruct( "Collection" , Collection.class ); - addStruct( "Collection" , Collection.class ); - addStruct( "Collection" , Collection.class ); - - addStruct( "List" , List.class ); - addStruct( "ArrayList" , ArrayList.class ); - addStruct( "List" , List.class ); - addStruct( "ArrayList" , ArrayList.class ); - addStruct( "List" , List.class ); - addStruct( "ArrayList" , ArrayList.class ); - - addStruct( "Set" , Set.class ); - addStruct( "HashSet" , HashSet.class ); - addStruct( "Set" , Set.class ); - addStruct( "HashSet" , HashSet.class ); - addStruct( "Set" , Set.class ); - addStruct( "HashSet" , HashSet.class ); - - addStruct( "Map" , Map.class ); - addStruct( "HashMap" , HashMap.class ); - addStruct( "Map" , Map.class ); - addStruct( "HashMap" , HashMap.class ); - addStruct( "Map" , Map.class ); - addStruct( "HashMap" , HashMap.class ); - addStruct( "Map" , Map.class ); - addStruct( "HashMap" , HashMap.class ); - - addStruct( "Executable" , Executable.class ); - - addStruct( "Exception" , Exception.class); - addStruct( "ArithmeticException" , ArithmeticException.class); - addStruct( "IllegalArgumentException" , IllegalArgumentException.class); - addStruct( "IllegalStateException" , IllegalStateException.class); - addStruct( "NumberFormatException" , NumberFormatException.class); - - addStruct( "GeoPoint" , GeoPoint.class); - addStruct( "Strings" , ScriptDocValues.Strings.class); - addStruct( "Longs" , ScriptDocValues.Longs.class); - addStruct( "Doubles" , ScriptDocValues.Doubles.class); - addStruct( "GeoPoints" , ScriptDocValues.GeoPoints.class); - - addStruct( "FeatureTest", FeatureTest.class); + /** adds classes from definition. returns hierarchy */ + private Map> addStructs() { + final Map> hierarchy = new HashMap<>(); + int currentLine = -1; + try { + try (InputStream stream = Definition.class.getResourceAsStream("definition.txt"); + LineNumberReader reader = new LineNumberReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { + String line = null; + while ((line = reader.readLine()) != null) { + currentLine = reader.getLineNumber(); + line = line.trim(); + if (line.length() == 0 || line.charAt(0) == '#') { + continue; + } + if (line.startsWith("class ")) { + String elements[] = line.split("\u0020"); + assert elements[2].equals("->"); + if (elements.length == 7) { + hierarchy.put(elements[1], Arrays.asList(elements[5].split(","))); + } else { + assert elements.length == 5; + } + String className = elements[1]; + String javaPeer = elements[3]; + final Class javaClazz; + switch (javaPeer) { + case "void": + javaClazz = void.class; + break; + case "boolean": + javaClazz = boolean.class; + break; + case "byte": + javaClazz = byte.class; + break; + case "short": + javaClazz = short.class; + break; + case "char": + javaClazz = char.class; + break; + case "int": + javaClazz = int.class; + break; + case "long": + javaClazz = long.class; + break; + case "float": + javaClazz = float.class; + break; + case "double": + javaClazz = double.class; + break; + default: + javaClazz = Class.forName(javaPeer); + break; + } + addStruct(className, javaClazz); + } + } + } + } catch (Exception e) { + throw new RuntimeException("syntax error in definition line: " + currentLine, e); + } + return hierarchy; } + /** adds class methods/fields/ctors */ private void addElements() { - addMethod("Object", "equals", null, false, booleanType, new Type[] {objectType}, null, null); - addMethod("Object", "hashCode", null, false, intType, new Type[] {}, null, null); - addMethod("Object", "toString", null, false, stringType, new Type[] {}, null, null); - - addMethod("def", "equals", null, false, booleanType, new Type[] {objectType}, null, null); - addMethod("def", "hashCode", null, false, intType, new Type[] {}, null, null); - addMethod("def", "toString", null, false, stringType, new Type[] {}, null, null); - - addConstructor("Boolean", "new", new Type[] {booleanType}, null); - addMethod("Boolean", "booleanValue", null, false, booleanType, new Type[] {}, null, null); - addMethod("Boolean", "compare", null, true, intType, new Type[] {booleanType,booleanType}, null, null); - addMethod("Boolean", "compareTo", null, false, intType, new Type[] {booleanobjType}, null, null); - addMethod("Boolean", "parseBoolean", null, true, booleanType, new Type[] {stringType}, null, null); - addMethod("Boolean", "valueOf", null, true, booleanobjType, new Type[] {booleanType}, null, null); - addField("Boolean", "FALSE", null, true, booleanobjType, null); - addField("Boolean", "TRUE", null, true, booleanobjType, null); - - addConstructor("Byte", "new", new Type[] {byteType}, null); - addMethod("Byte", "compare", null, true, intType, new Type[] {byteType,byteType}, null, null); - addMethod("Byte", "compareTo", null, false, intType, new Type[] {byteobjType}, null, null); - addMethod("Byte", "parseByte", null, true, byteType, new Type[] {stringType}, null, null); - addMethod("Byte", "valueOf", null, true, byteobjType, new Type[] {byteType}, null, null); - addField("Byte", "MIN_VALUE", null, true, byteType, null); - addField("Byte", "MAX_VALUE", null, true, byteType, null); - - addConstructor("Short", "new", new Type[] {shortType}, null); - addMethod("Short", "compare", null, true, intType, new Type[] {shortType,shortType}, null, null); - addMethod("Short", "compareTo", null, false, intType, new Type[] {shortobjType}, null, null); - addMethod("Short", "parseShort", null, true, shortType, new Type[] {stringType}, null, null); - addMethod("Short", "valueOf", null, true, shortobjType, new Type[] {shortType}, null, null); - addField("Short", "MIN_VALUE", null, true, shortType, null); - addField("Short", "MAX_VALUE", null, true, shortType, null); - - addConstructor("Character", "new", new Type[] {charType}, null); - addMethod("Character", "charCount", null, true, intType, new Type[] {intType}, null, null); - addMethod("Character", "charValue", null, false, charType, new Type[] {}, null, null); - addMethod("Character", "compare", null, true, intType, new Type[] {charType,charType}, null, null); - addMethod("Character", "compareTo", null, false, intType, new Type[] {charobjType}, null, null); - addMethod("Character", "digit", null, true, intType, new Type[] {intType,intType}, null, null); - addMethod("Character", "forDigit", null, true, charType, new Type[] {intType,intType}, null, null); - addMethod("Character", "getName", null, true, stringType, new Type[] {intType}, null, null); - addMethod("Character", "getNumericValue", null, true, intType, new Type[] {intType}, null, null); - addMethod("Character", "isAlphabetic", null, true, booleanType, new Type[] {intType}, null, null); - addMethod("Character", "isDefined", null, true, booleanType, new Type[] {intType}, null, null); - addMethod("Character", "isDigit", null, true, booleanType, new Type[] {intType}, null, null); - addMethod("Character", "isIdeographic", null, true, booleanType, new Type[] {intType}, null, null); - addMethod("Character", "isLetter", null, true, booleanType, new Type[] {intType}, null, null); - addMethod("Character", "isLetterOrDigit", null, true, booleanType, new Type[] {intType}, null, null); - addMethod("Character", "isLowerCase", null, true, booleanType, new Type[] {intType}, null, null); - addMethod("Character", "isMirrored", null, true, booleanType, new Type[] {intType}, null, null); - addMethod("Character", "isSpaceChar", null, true, booleanType, new Type[] {intType}, null, null); - addMethod("Character", "isTitleCase", null, true, booleanType, new Type[] {intType}, null, null); - addMethod("Character", "isUpperCase", null, true, booleanType, new Type[] {intType}, null, null); - addMethod("Character", "isWhitespace", null, true, booleanType, new Type[] {intType}, null, null); - addMethod("Character", "valueOf", null, true, charobjType, new Type[] {charType}, null, null); - addField("Character", "MIN_VALUE", null, true, charType, null); - addField("Character", "MAX_VALUE", null, true, charType, null); - - addConstructor("Integer", "new", new Type[] {intType}, null); - addMethod("Integer", "compare", null, true, intType, new Type[] {intType,intType}, null, null); - addMethod("Integer", "compareTo", null, false, intType, new Type[] {intobjType}, null, null); - addMethod("Integer", "min", null, true, intType, new Type[] {intType,intType}, null, null); - addMethod("Integer", "max", null, true, intType, new Type[] {intType,intType}, null, null); - addMethod("Integer", "parseInt", null, true, intType, new Type[] {stringType}, null, null); - addMethod("Integer", "signum", null, true, intType, new Type[] {intType}, null, null); - addMethod("Integer", "toHexString", null, true, stringType, new Type[] {intType}, null, null); - addMethod("Integer", "valueOf", null, true, intobjType, new Type[] {intType}, null, null); - addField("Integer", "MIN_VALUE", null, true, intType, null); - addField("Integer", "MAX_VALUE", null, true, intType, null); - - addConstructor("Long", "new", new Type[] {longType}, null); - addMethod("Long", "compare", null, true, intType, new Type[] {longType,longType}, null, null); - addMethod("Long", "compareTo", null, false, intType, new Type[] {longobjType}, null, null); - addMethod("Long", "min", null, true, longType, new Type[] {longType,longType}, null, null); - addMethod("Long", "max", null, true, longType, new Type[] {longType,longType}, null, null); - addMethod("Long", "parseLong", null, true, longType, new Type[] {stringType}, null, null); - addMethod("Long", "signum", null, true, intType, new Type[] {longType}, null, null); - addMethod("Long", "toHexString", null, true, stringType, new Type[] {longType}, null, null); - addMethod("Long", "valueOf", null, true, longobjType, new Type[] {longType}, null, null); - addField("Long", "MIN_VALUE", null, true, longType, null); - addField("Long", "MAX_VALUE", null, true, longType, null); - - addConstructor("Float", "new", new Type[] {floatType}, null); - addMethod("Float", "compare", null, true, intType, new Type[] {floatType,floatType}, null, null); - addMethod("Float", "compareTo", null, false, intType, new Type[] {floatobjType}, null, null); - addMethod("Float", "min", null, true, floatType, new Type[] {floatType,floatType}, null, null); - addMethod("Float", "max", null, true, floatType, new Type[] {floatType,floatType}, null, null); - addMethod("Float", "parseFloat", null, true, floatType, new Type[] {stringType}, null, null); - addMethod("Float", "toHexString", null, true, stringType, new Type[] {floatType}, null, null); - addMethod("Float", "valueOf", null, true, floatobjType, new Type[] {floatType}, null, null); - addField("Float", "MIN_VALUE", null, true, floatType, null); - addField("Float", "MAX_VALUE", null, true, floatType, null); - - addConstructor("Double", "new", new Type[] {doubleType}, null); - addMethod("Double", "compare", null, true, intType, new Type[] {doubleType,doubleType}, null, null); - addMethod("Double", "compareTo", null, false, intType, new Type[] {doubleobjType}, null, null); - addMethod("Double", "min", null, true, doubleType, new Type[] {doubleType,doubleType}, null, null); - addMethod("Double", "max", null, true, doubleType, new Type[] {doubleType,doubleType}, null, null); - addMethod("Double", "parseDouble", null, true, doubleType, new Type[] {stringType}, null, null); - addMethod("Double", "toHexString", null, true, stringType, new Type[] {doubleType}, null, null); - addMethod("Double", "valueOf", null, true, doubleobjType, new Type[] {doubleType}, null, null); - addField("Double", "MIN_VALUE", null, true, doubleType, null); - addField("Double", "MAX_VALUE", null, true, doubleType, null); - - addMethod("Number", "byteValue", null, false, byteType, new Type[] {}, null, null); - addMethod("Number", "shortValue", null, false, shortType, new Type[] {}, null, null); - addMethod("Number", "intValue", null, false, intType, new Type[] {}, null, null); - addMethod("Number", "longValue", null, false, longType, new Type[] {}, null, null); - addMethod("Number", "floatValue", null, false, floatType, new Type[] {}, null, null); - addMethod("Number", "doubleValue", null, false, doubleType, new Type[] {}, null, null); - - addMethod("CharSequence", "charAt", null, false, charType, new Type[] {intType}, null, null); - addMethod("CharSequence", "length", null, false, intType, new Type[] {}, null, null); - - addConstructor("String", "new", new Type[] {}, null); - addMethod("String", "codePointAt", null, false, intType, new Type[] {intType}, null, null); - addMethod("String", "compareTo", null, false, intType, new Type[] {stringType}, null, null); - addMethod("String", "concat", null, false, stringType, new Type[] {stringType}, null, null); - addMethod("String", "endsWith", null, false, booleanType, new Type[] {stringType}, null, null); - addMethod("String", "indexOf", null, false, intType, new Type[] {stringType}, null, null); - addMethod("String", "indexOf", null, false, intType, new Type[] {stringType, intType}, null, null); - addMethod("String", "isEmpty", null, false, booleanType, new Type[] {}, null, null); - addMethod("String", "replace", null, false, stringType, new Type[] {charseqType, charseqType}, null, null); - addMethod("String", "startsWith", null, false, booleanType, new Type[] {stringType}, null, null); - addMethod("String", "substring", null, false, stringType, new Type[] {intType, intType}, null, null); - addMethod("String", "toCharArray", null, false, getType(charType.struct, 1), new Type[] {}, null, null); - addMethod("String", "trim", null, false, stringType, new Type[] {}, null, null); - - addMethod("Utility", "NumberToboolean", null, true, booleanType, new Type[] {numberType}, null, null); - addMethod("Utility", "NumberTochar", null, true, charType, new Type[] {numberType}, null, null); - addMethod("Utility", "NumberToBoolean", null, true, booleanobjType, new Type[] {numberType}, null, null); - addMethod("Utility", "NumberToByte", null, true, byteobjType, new Type[] {numberType}, null, null); - addMethod("Utility", "NumberToShort", null, true, shortobjType, new Type[] {numberType}, null, null); - addMethod("Utility", "NumberToCharacter", null, true, charobjType, new Type[] {numberType}, null, null); - addMethod("Utility", "NumberToInteger", null, true, intobjType, new Type[] {numberType}, null, null); - addMethod("Utility", "NumberToLong", null, true, longobjType, new Type[] {numberType}, null, null); - addMethod("Utility", "NumberToFloat", null, true, floatobjType, new Type[] {numberType}, null, null); - addMethod("Utility", "NumberToDouble", null, true, doubleobjType, new Type[] {numberType}, null, null); - addMethod("Utility", "booleanTobyte", null, true, byteType, new Type[] {booleanType}, null, null); - addMethod("Utility", "booleanToshort", null, true, shortType, new Type[] {booleanType}, null, null); - addMethod("Utility", "booleanTochar", null, true, charType, new Type[] {booleanType}, null, null); - addMethod("Utility", "booleanToint", null, true, intType, new Type[] {booleanType}, null, null); - addMethod("Utility", "booleanTolong", null, true, longType, new Type[] {booleanType}, null, null); - addMethod("Utility", "booleanTofloat", null, true, floatType, new Type[] {booleanType}, null, null); - addMethod("Utility", "booleanTodouble", null, true, doubleType, new Type[] {booleanType}, null, null); - addMethod("Utility", "booleanToInteger", null, true, intobjType, new Type[] {booleanType}, null, null); - addMethod("Utility", "BooleanTobyte", null, true, byteType, new Type[] {booleanobjType}, null, null); - addMethod("Utility", "BooleanToshort", null, true, shortType, new Type[] {booleanobjType}, null, null); - addMethod("Utility", "BooleanTochar", null, true, charType, new Type[] {booleanobjType}, null, null); - addMethod("Utility", "BooleanToint", null, true, intType, new Type[] {booleanobjType}, null, null); - addMethod("Utility", "BooleanTolong", null, true, longType, new Type[] {booleanobjType}, null, null); - addMethod("Utility", "BooleanTofloat", null, true, floatType, new Type[] {booleanobjType}, null, null); - addMethod("Utility", "BooleanTodouble", null, true, doubleType, new Type[] {booleanobjType}, null, null); - addMethod("Utility", "BooleanToByte", null, true, byteobjType, new Type[] {booleanobjType}, null, null); - addMethod("Utility", "BooleanToShort", null, true, shortobjType, new Type[] {booleanobjType}, null, null); - addMethod("Utility", "BooleanToCharacter", null, true, charobjType, new Type[] {booleanobjType}, null, null); - addMethod("Utility", "BooleanToInteger", null, true, intobjType, new Type[] {booleanobjType}, null, null); - addMethod("Utility", "BooleanToLong", null, true, longobjType, new Type[] {booleanobjType}, null, null); - addMethod("Utility", "BooleanToFloat", null, true, floatobjType, new Type[] {booleanobjType}, null, null); - addMethod("Utility", "BooleanToDouble", null, true, doubleobjType, new Type[] {booleanobjType}, null, null); - addMethod("Utility", "byteToboolean", null, true, booleanType, new Type[] {byteType}, null, null); - addMethod("Utility", "byteToShort", null, true, shortobjType, new Type[] {byteType}, null, null); - addMethod("Utility", "byteToCharacter", null, true, charobjType, new Type[] {byteType}, null, null); - addMethod("Utility", "byteToInteger", null, true, intobjType, new Type[] {byteType}, null, null); - addMethod("Utility", "byteToLong", null, true, longobjType, new Type[] {byteType}, null, null); - addMethod("Utility", "byteToFloat", null, true, floatobjType, new Type[] {byteType}, null, null); - addMethod("Utility", "byteToDouble", null, true, doubleobjType, new Type[] {byteType}, null, null); - addMethod("Utility", "ByteToboolean", null, true, booleanType, new Type[] {byteobjType}, null, null); - addMethod("Utility", "ByteTochar", null, true, charType, new Type[] {byteobjType}, null, null); - addMethod("Utility", "shortToboolean", null, true, booleanType, new Type[] {shortType}, null, null); - addMethod("Utility", "shortToByte", null, true, byteobjType, new Type[] {shortType}, null, null); - addMethod("Utility", "shortToCharacter", null, true, charobjType, new Type[] {shortType}, null, null); - addMethod("Utility", "shortToInteger", null, true, intobjType, new Type[] {shortType}, null, null); - addMethod("Utility", "shortToLong", null, true, longobjType, new Type[] {shortType}, null, null); - addMethod("Utility", "shortToFloat", null, true, floatobjType, new Type[] {shortType}, null, null); - addMethod("Utility", "shortToDouble", null, true, doubleobjType, new Type[] {shortType}, null, null); - addMethod("Utility", "ShortToboolean", null, true, booleanType, new Type[] {shortobjType}, null, null); - addMethod("Utility", "ShortTochar", null, true, charType, new Type[] {shortobjType}, null, null); - addMethod("Utility", "charToboolean", null, true, booleanType, new Type[] {charType}, null, null); - addMethod("Utility", "charToByte", null, true, byteobjType, new Type[] {charType}, null, null); - addMethod("Utility", "charToShort", null, true, shortobjType, new Type[] {charType}, null, null); - addMethod("Utility", "charToInteger", null, true, intobjType, new Type[] {charType}, null, null); - addMethod("Utility", "charToLong", null, true, longobjType, new Type[] {charType}, null, null); - addMethod("Utility", "charToFloat", null, true, floatobjType, new Type[] {charType}, null, null); - addMethod("Utility", "charToDouble", null, true, doubleobjType, new Type[] {charType}, null, null); - addMethod("Utility", "charToString", null, true, stringType, new Type[] {charType}, null, null); - addMethod("Utility", "CharacterToboolean", null, true, booleanType, new Type[] {charobjType}, null, null); - addMethod("Utility", "CharacterTobyte", null, true, byteType, new Type[] {charobjType}, null, null); - addMethod("Utility", "CharacterToshort", null, true, shortType, new Type[] {charobjType}, null, null); - addMethod("Utility", "CharacterToint", null, true, intType, new Type[] {charobjType}, null, null); - addMethod("Utility", "CharacterTolong", null, true, longType, new Type[] {charobjType}, null, null); - addMethod("Utility", "CharacterTofloat", null, true, floatType, new Type[] {charobjType}, null, null); - addMethod("Utility", "CharacterTodouble", null, true, doubleType, new Type[] {charobjType}, null, null); - addMethod("Utility", "CharacterToBoolean", null, true, booleanobjType, new Type[] {charobjType}, null, null); - addMethod("Utility", "CharacterToByte", null, true, byteobjType, new Type[] {charobjType}, null, null); - addMethod("Utility", "CharacterToShort", null, true, shortobjType, new Type[] {charobjType}, null, null); - addMethod("Utility", "CharacterToInteger", null, true, intobjType, new Type[] {charobjType}, null, null); - addMethod("Utility", "CharacterToLong", null, true, longobjType, new Type[] {charobjType}, null, null); - addMethod("Utility", "CharacterToFloat", null, true, floatobjType, new Type[] {charobjType}, null, null); - addMethod("Utility", "CharacterToDouble", null, true, doubleobjType, new Type[] {charobjType}, null, null); - addMethod("Utility", "CharacterToString", null, true, stringType, new Type[] {charobjType}, null, null); - addMethod("Utility", "intToboolean", null, true, booleanType, new Type[] {intType}, null, null); - addMethod("Utility", "intToByte", null, true, byteobjType, new Type[] {intType}, null, null); - addMethod("Utility", "intToShort", null, true, shortobjType, new Type[] {intType}, null, null); - addMethod("Utility", "intToCharacter", null, true, charobjType, new Type[] {intType}, null, null); - addMethod("Utility", "intToLong", null, true, longobjType, new Type[] {intType}, null, null); - addMethod("Utility", "intToFloat", null, true, floatobjType, new Type[] {intType}, null, null); - addMethod("Utility", "intToDouble", null, true, doubleobjType, new Type[] {intType}, null, null); - addMethod("Utility", "IntegerToboolean", null, true, booleanType, new Type[] {intobjType}, null, null); - addMethod("Utility", "IntegerTochar", null, true, charType, new Type[] {intobjType}, null, null); - addMethod("Utility", "longToboolean", null, true, booleanType, new Type[] {longType}, null, null); - addMethod("Utility", "longToByte", null, true, byteobjType, new Type[] {longType}, null, null); - addMethod("Utility", "longToShort", null, true, shortobjType, new Type[] {longType}, null, null); - addMethod("Utility", "longToCharacter", null, true, charobjType, new Type[] {longType}, null, null); - addMethod("Utility", "longToInteger", null, true, intobjType, new Type[] {longType}, null, null); - addMethod("Utility", "longToFloat", null, true, floatobjType, new Type[] {longType}, null, null); - addMethod("Utility", "longToDouble", null, true, doubleobjType, new Type[] {longType}, null, null); - addMethod("Utility", "LongToboolean", null, true, booleanType, new Type[] {longobjType}, null, null); - addMethod("Utility", "LongTochar", null, true, charType, new Type[] {longobjType}, null, null); - addMethod("Utility", "floatToboolean", null, true, booleanType, new Type[] {floatType}, null, null); - addMethod("Utility", "floatToByte", null, true, byteobjType, new Type[] {floatType}, null, null); - addMethod("Utility", "floatToShort", null, true, shortobjType, new Type[] {floatType}, null, null); - addMethod("Utility", "floatToCharacter", null, true, charobjType, new Type[] {floatType}, null, null); - addMethod("Utility", "floatToInteger", null, true, intobjType, new Type[] {floatType}, null, null); - addMethod("Utility", "floatToLong", null, true, longobjType, new Type[] {floatType}, null, null); - addMethod("Utility", "floatToDouble", null, true, doubleobjType, new Type[] {floatType}, null, null); - addMethod("Utility", "FloatToboolean", null, true, booleanType, new Type[] {floatobjType}, null, null); - addMethod("Utility", "FloatTochar", null, true, charType, new Type[] {floatobjType}, null, null); - addMethod("Utility", "doubleToboolean", null, true, booleanType, new Type[] {doubleType}, null, null); - addMethod("Utility", "doubleToByte", null, true, byteobjType, new Type[] {doubleType}, null, null); - addMethod("Utility", "doubleToShort", null, true, shortobjType, new Type[] {doubleType}, null, null); - addMethod("Utility", "doubleToCharacter", null, true, charobjType, new Type[] {doubleType}, null, null); - addMethod("Utility", "doubleToInteger", null, true, intobjType, new Type[] {doubleType}, null, null); - addMethod("Utility", "doubleToLong", null, true, longobjType, new Type[] {doubleType}, null, null); - addMethod("Utility", "doubleToFloat", null, true, floatobjType, new Type[] {doubleType}, null, null); - addMethod("Utility", "DoubleToboolean", null, true, booleanType, new Type[] {doubleobjType}, null, null); - addMethod("Utility", "DoubleTochar", null, true, charType, new Type[] {doubleobjType}, null, null); - addMethod("Utility", "StringTochar", null, true, charType, new Type[] {stringType}, null, null); - addMethod("Utility", "StringToCharacter", null, true, charobjType, new Type[] {stringType}, null, null); - - addMethod("Math", "abs", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "acos", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "asin", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "atan", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "atan2", null, true, doubleType, new Type[] {doubleType, doubleType}, null, null); - addMethod("Math", "cbrt", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "ceil", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "cos", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "cosh", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "exp", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "expm1", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "floor", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "hypot", null, true, doubleType, new Type[] {doubleType, doubleType}, null, null); - addMethod("Math", "log", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "log10", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "log1p", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "max", null, true, doubleType, new Type[] {doubleType, doubleType}, null, null); - addMethod("Math", "min", null, true, doubleType, new Type[] {doubleType, doubleType}, null, null); - addMethod("Math", "pow", null, true, doubleType, new Type[] {doubleType, doubleType}, null, null); - addMethod("Math", "random", null, true, doubleType, new Type[] {}, null, null); - addMethod("Math", "rint", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "round", null, true, longType, new Type[] {doubleType}, null, null); - addMethod("Math", "sin", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "sinh", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "sqrt", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "tan", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "tanh", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "toDegrees", null, true, doubleType, new Type[] {doubleType}, null, null); - addMethod("Math", "toRadians", null, true, doubleType, new Type[] {doubleType}, null, null); - addField("Math", "E", null, true, doubleType, null); - addField("Math", "PI", null, true, doubleType, null); - - addMethod("Def", "DefTobyteImplicit", null, true, byteType, new Type[] {defType}, null, null); - addMethod("Def", "DefToshortImplicit", null, true, shortType, new Type[] {defType}, null, null); - addMethod("Def", "DefTocharImplicit", null, true, charType, new Type[] {defType}, null, null); - addMethod("Def", "DefTointImplicit", null, true, intType, new Type[] {defType}, null, null); - addMethod("Def", "DefTolongImplicit", null, true, longType, new Type[] {defType}, null, null); - addMethod("Def", "DefTofloatImplicit", null, true, floatType, new Type[] {defType}, null, null); - addMethod("Def", "DefTodoubleImplicit", null, true, doubleType, new Type[] {defType}, null, null); - addMethod("Def", "DefToByteImplicit", null, true, byteobjType, new Type[] {defType}, null, null); - addMethod("Def", "DefToShortImplicit", null, true, shortobjType, new Type[] {defType}, null, null); - addMethod("Def", "DefToCharacterImplicit", null, true, charobjType, new Type[] {defType}, null, null); - addMethod("Def", "DefToIntegerImplicit", null, true, intobjType, new Type[] {defType}, null, null); - addMethod("Def", "DefToLongImplicit", null, true, longobjType, new Type[] {defType}, null, null); - addMethod("Def", "DefToFloatImplicit", null, true, floatobjType, new Type[] {defType}, null, null); - addMethod("Def", "DefToDoubleImplicit", null, true, doubleobjType, new Type[] {defType}, null, null); - addMethod("Def", "DefTobyteExplicit", null, true, byteType, new Type[] {defType}, null, null); - addMethod("Def", "DefToshortExplicit", null, true, shortType, new Type[] {defType}, null, null); - addMethod("Def", "DefTocharExplicit", null, true, charType, new Type[] {defType}, null, null); - addMethod("Def", "DefTointExplicit", null, true, intType, new Type[] {defType}, null, null); - addMethod("Def", "DefTolongExplicit", null, true, longType, new Type[] {defType}, null, null); - addMethod("Def", "DefTofloatExplicit", null, true, floatType, new Type[] {defType}, null, null); - addMethod("Def", "DefTodoubleExplicit", null, true, doubleType, new Type[] {defType}, null, null); - addMethod("Def", "DefToByteExplicit", null, true, byteobjType, new Type[] {defType}, null, null); - addMethod("Def", "DefToShortExplicit", null, true, shortobjType, new Type[] {defType}, null, null); - addMethod("Def", "DefToCharacterExplicit", null, true, charobjType, new Type[] {defType}, null, null); - addMethod("Def", "DefToIntegerExplicit", null, true, intobjType, new Type[] {defType}, null, null); - addMethod("Def", "DefToLongExplicit", null, true, longobjType, new Type[] {defType}, null, null); - addMethod("Def", "DefToFloatExplicit", null, true, floatobjType, new Type[] {defType}, null, null); - addMethod("Def", "DefToDoubleExplicit", null, true, doubleobjType, new Type[] {defType}, null, null); - - addMethod("Iterator", "hasNext", null, false, booleanType, new Type[] {}, null, null); - addMethod("Iterator", "next", null, false, objectType, new Type[] {}, defType, null); - addMethod("Iterator", "remove", null, false, voidType, new Type[] {}, null, null); - - addMethod("Iterator", "hasNext", null, false, booleanType, new Type[] {}, null, null); - addMethod("Iterator", "next", null, false, objectType, new Type[] {}, null, null); - addMethod("Iterator", "remove", null, false, voidType, new Type[] {}, null, null); - - addMethod("Iterator", "hasNext", null, false, booleanType, new Type[] {}, null, null); - addMethod("Iterator", "next", null, false, objectType, new Type[] {}, stringType, null); - addMethod("Iterator", "remove", null, false, voidType, new Type[] {}, null, null); - - addMethod("Collection", "add", null, false, booleanType, new Type[] {objectType}, null, new Type[] {defType}); - addMethod("Collection", "clear", null, false, voidType, new Type[] {}, null, null); - addMethod("Collection", "contains", null, false, booleanType, new Type[] {objectType}, null, new Type[] {defType}); - addMethod("Collection", "isEmpty", null, false, booleanType, new Type[] {}, null, null); - addMethod("Collection", "iterator", null, false, itrType, new Type[] {}, null, null); - addMethod("Collection", "remove", null, false, booleanType, new Type[] {objectType}, null, new Type[] {defType}); - addMethod("Collection", "size", null, false, intType, new Type[] {}, null, null); - - addMethod("Collection", "add", null, false, booleanType, new Type[] {objectType}, null, null); - addMethod("Collection", "clear", null, false, voidType, new Type[] {}, null, null); - addMethod("Collection", "contains", null, false, booleanType, new Type[] {objectType}, null, null); - addMethod("Collection", "isEmpty", null, false, booleanType, new Type[] {}, null, null); - addMethod("Collection", "iterator", null, false, oitrType, new Type[] {}, null, null); - addMethod("Collection", "remove", null, false, booleanType, new Type[] {objectType}, null, null); - addMethod("Collection", "size", null, false, intType, new Type[] {}, null, null); - - addMethod("Collection", "add", null, false, booleanType, new Type[] {objectType}, null, new Type[] {stringType}); - addMethod("Collection", "clear", null, false, voidType, new Type[] {}, null, null); - addMethod("Collection", "contains", null, false, booleanType, new Type[] {objectType}, null, new Type[] {stringType}); - addMethod("Collection", "isEmpty", null, false, booleanType, new Type[] {}, null, null); - addMethod("Collection", "iterator", null, false, sitrType, new Type[] {}, null, null); - addMethod("Collection", "remove", null, false, booleanType, new Type[] {objectType}, null, new Type[] {stringType}); - addMethod("Collection", "size", null, false, intType, new Type[] {}, null, null); - - addMethod("List", "set", null, false, objectType, new Type[] {intType, objectType}, defType, new Type[] {intType, defType}); - addMethod("List", "get", null, false, objectType, new Type[] {intType}, defType, null); - addMethod("List", "remove", null, false, objectType, new Type[] {intType}, defType, null); - addMethod("List", "getLength", "size", false, intType, new Type[] {}, null, null); - - addConstructor("ArrayList", "new", new Type[] {}, null); - - addMethod("List", "set", null, false, objectType, new Type[] {intType, objectType}, null, null); - addMethod("List", "get", null, false, objectType, new Type[] {intType}, null, null); - addMethod("List", "remove", null, false, objectType, new Type[] {intType}, null, null); - addMethod("List", "getLength", "size", false, intType, new Type[] {}, null, null); - - addConstructor("ArrayList", "new", new Type[] {}, null); - - addMethod("List", "set", null, false, objectType, new Type[] {intType, objectType}, stringType, - new Type[] {intType, stringType}); - addMethod("List", "get", null, false, objectType, new Type[] {intType}, stringType, null); - addMethod("List", "remove", null, false, objectType, new Type[] {intType}, stringType, null); - addMethod("List", "getLength", "size", false, intType, new Type[] {}, null, null); - - addConstructor("ArrayList", "new", new Type[] {}, null); - - addConstructor("HashSet", "new", new Type[] {}, null); - - addConstructor("HashSet", "new", new Type[] {}, null); - - addConstructor("HashSet", "new", new Type[] {}, null); - - addMethod("Map", "put", null, false, objectType, new Type[] {objectType, objectType}, defType, new Type[] {defType, defType}); - addMethod("Map", "get", null, false, objectType, new Type[] {objectType}, defType, new Type[] {defType}); - addMethod("Map", "remove", null, false, objectType, new Type[] {objectType}, null, null); - addMethod("Map", "isEmpty", null, false, booleanType, new Type[] {}, null, null); - addMethod("Map", "size", null, false, intType, new Type[] {}, null, null); - addMethod("Map", "containsKey", null, false, booleanType, new Type[] {objectType}, null, new Type[] {defType}); - addMethod("Map", "containsValue", null, false, booleanType, new Type[] {objectType}, null, new Type[] {defType}); - addMethod("Map", "keySet", null, false, osetType, new Type[] {}, setType, null); - addMethod("Map", "values", null, false, ocollectionType, new Type[] {}, collectionType, null); - - addConstructor("HashMap", "new", new Type[] {}, null); - - addMethod("Map", "put", null, false, objectType, new Type[] {objectType, objectType}, null, null); - addMethod("Map", "get", null, false, objectType, new Type[] {objectType}, null, null); - addMethod("Map", "remove", null, false, objectType, new Type[] {objectType}, null, null); - addMethod("Map", "isEmpty", null, false, booleanType, new Type[] {}, null, null); - addMethod("Map", "size", null, false, intType, new Type[] {}, null, null); - addMethod("Map", "containsKey", null, false, booleanType, new Type[] {objectType}, null, null); - addMethod("Map", "containsValue", null, false, booleanType, new Type[] {objectType}, null, null); - addMethod("Map", "keySet", null, false, osetType, new Type[] {}, null, null); - addMethod("Map", "values", null, false, ocollectionType, new Type[] {}, null, null); - - addConstructor("HashMap", "new", new Type[] {}, null); - - addMethod("Map", "put", null, false, objectType, new Type[] {objectType, objectType}, defType, - new Type[] {stringType, defType}); - addMethod("Map", "get", null, false, objectType, new Type[] {objectType}, defType, new Type[] {stringType}); - addMethod("Map", "remove", null, false, objectType, new Type[] {objectType}, defType, new Type[] {stringType}); - addMethod("Map", "isEmpty", null, false, booleanType, new Type[] {}, null, null); - addMethod("Map", "size", null, false, intType, new Type[] {}, null, null); - addMethod("Map", "containsKey", null, false, booleanType, new Type[] {objectType}, null, new Type[] {stringType}); - addMethod("Map", "containsValue", null, false, booleanType, new Type[] {objectType}, null, new Type[] {defType}); - addMethod("Map", "keySet", null, false, osetType, new Type[] {}, ssetType, null); - addMethod("Map", "values", null, false, ocollectionType, new Type[] {}, collectionType, null); - - addConstructor("HashMap", "new", new Type[] {}, null); - - addMethod("Map", "put", null, false, objectType, new Type[] {objectType, objectType}, null, - new Type[] {stringType, objectType}); - addMethod("Map", "get", null, false, objectType, new Type[] {objectType}, null, new Type[] {stringType}); - addMethod("Map", "remove", null, false, objectType, new Type[] {objectType}, null, new Type[] {stringType}); - addMethod("Map", "isEmpty", null, false, booleanType, new Type[] {}, null, null); - addMethod("Map", "size", null, false, intType, new Type[] {}, null, null); - addMethod("Map", "containsKey", null, false, booleanType, new Type[] {objectType}, null, new Type[] {stringType}); - addMethod("Map", "containsValue", null, false, booleanType, new Type[] {objectType}, null, null); - addMethod("Map", "keySet", null, false, osetType, new Type[] {}, ssetType, null); - addMethod("Map", "values", null, false, ocollectionType, new Type[] {}, null, null); - - addConstructor("HashMap", "new", new Type[] {}, null); - - addMethod("Exception", "getMessage", null, false, stringType, new Type[] {}, null, null); - - addConstructor("ArithmeticException", "new", new Type[] {stringType}, null); - - addConstructor("IllegalArgumentException", "new", new Type[] {stringType}, null); - - addConstructor("IllegalStateException", "new", new Type[] {stringType}, null); - - addConstructor("NumberFormatException", "new", new Type[] {stringType}, null); - - addMethod("GeoPoint", "getLat", null, false, doubleType, new Type[] {}, null, null); - addMethod("GeoPoint", "getLon", null, false, doubleType, new Type[] {}, null, null); - addMethod("Strings", "getValue", null, false, stringType, new Type[] {}, null, null); - addMethod("Strings", "getValues", null, false, slistType, new Type[] {}, null, null); - addMethod("Longs", "getValue", null, false, longType, new Type[] {}, null, null); - addMethod("Longs", "getValues", null, false, olistType, new Type[] {}, null, null); - // TODO: add better date support for Longs here? (carefully?) - addMethod("Doubles", "getValue", null, false, doubleType, new Type[] {}, null, null); - addMethod("Doubles", "getValues", null, false, olistType, new Type[] {}, null, null); - addMethod("GeoPoints", "getValue", null, false, geoPointType, new Type[] {}, null, null); - addMethod("GeoPoints", "getValues", null, false, olistType, new Type[] {}, null, null); - addMethod("GeoPoints", "getLat", null, false, doubleType, new Type[] {}, null, null); - addMethod("GeoPoints", "getLon", null, false, doubleType, new Type[] {}, null, null); - addMethod("GeoPoints", "getLats", null, false, getType(doubleType.struct, 1), new Type[] {}, null, null); - addMethod("GeoPoints", "getLons", null, false, getType(doubleType.struct, 1), new Type[] {}, null, null); - // geo distance functions... so many... - addMethod("GeoPoints", "factorDistance", null, false, doubleType, - new Type[] { doubleType, doubleType }, null, null); - addMethod("GeoPoints", "factorDistanceWithDefault", null, false, doubleType, - new Type[] { doubleType, doubleType, doubleType }, null, null); - addMethod("GeoPoints", "factorDistance02", null, false, doubleType, - new Type[] { doubleType, doubleType }, null, null); - addMethod("GeoPoints", "factorDistance13", null, false, doubleType, - new Type[] { doubleType, doubleType }, null, null); - addMethod("GeoPoints", "arcDistance", null, false, doubleType, - new Type[] { doubleType, doubleType }, null, null); - addMethod("GeoPoints", "arcDistanceWithDefault", null, false, doubleType, - new Type[] { doubleType, doubleType, doubleType }, null, null); - addMethod("GeoPoints", "arcDistanceInKm", null, false, doubleType, - new Type[] { doubleType, doubleType }, null, null); - addMethod("GeoPoints", "arcDistanceInKmWithDefault", null, false, doubleType, - new Type[] { doubleType, doubleType, doubleType }, null, null); - addMethod("GeoPoints", "arcDistanceInMiles", null, false, doubleType, - new Type[] { doubleType, doubleType }, null, null); - addMethod("GeoPoints", "arcDistanceInMilesWithDefault", null, false, doubleType, - new Type[] { doubleType, doubleType, doubleType }, null, null); - addMethod("GeoPoints", "distance", null, false, doubleType, - new Type[] { doubleType, doubleType }, null, null); - addMethod("GeoPoints", "distanceWithDefault", null, false, doubleType, - new Type[] { doubleType, doubleType, doubleType }, null, null); - addMethod("GeoPoints", "distanceInKm", null, false, doubleType, - new Type[] { doubleType, doubleType }, null, null); - addMethod("GeoPoints", "distanceInKmWithDefault", null, false, doubleType, - new Type[] { doubleType, doubleType, doubleType }, null, null); - addMethod("GeoPoints", "distanceInMiles", null, false, doubleType, - new Type[] { doubleType, doubleType }, null, null); - addMethod("GeoPoints", "distanceInMilesWithDefault", null, false, doubleType, - new Type[] { doubleType, doubleType, doubleType }, null, null); - addMethod("GeoPoints", "geohashDistance", null, false, doubleType, - new Type[] { stringType }, null, null); - addMethod("GeoPoints", "geohashDistanceInKm", null, false, doubleType, - new Type[] { stringType }, null, null); - addMethod("GeoPoints", "geohashDistanceInMiles", null, false, doubleType, - new Type[] { stringType }, null, null); - - // currently FeatureTest exposes overloaded constructor, field load store, and overloaded static methods - addConstructor("FeatureTest", "new", new Type[] {}, null); - addConstructor("FeatureTest", "new", new Type[] {intType, intType}, null); - addMethod("FeatureTest", "getX", null, false, intType, new Type[] {}, null, null); - addMethod("FeatureTest", "getY", null, false, intType, new Type[] {}, null, null); - addMethod("FeatureTest", "setX", null, false, voidType, new Type[] {intType}, null, null); - addMethod("FeatureTest", "setY", null, false, voidType, new Type[] {intType}, null, null); - addMethod("FeatureTest", "overloadedStatic", null, true, booleanType, new Type[] {}, null, null); - addMethod("FeatureTest", "overloadedStatic", null, true, booleanType, new Type[] {booleanType}, null, null); - } - - private void copyStructs() { - copyStruct("Void", "Object"); - copyStruct("Boolean", "Object"); - copyStruct("Byte", "Number", "Object"); - copyStruct("Short", "Number", "Object"); - copyStruct("Character", "Object"); - copyStruct("Integer", "Number", "Object"); - copyStruct("Long", "Number", "Object"); - copyStruct("Float", "Number", "Object"); - copyStruct("Double", "Number", "Object"); - - copyStruct("Number", "Object"); - copyStruct("CharSequence", "Object"); - copyStruct("String", "CharSequence", "Object"); - - copyStruct("List", "Collection", "Object"); - copyStruct("ArrayList", "List", "Collection", "Object"); - copyStruct("List", "Collection", "Object"); - copyStruct("ArrayList", "List", "Collection", "Object"); - copyStruct("List", "Collection", "Object"); - copyStruct("ArrayList", "List", "Collection", "Object"); - - copyStruct("Set", "Collection", "Object"); - copyStruct("HashSet", "Set", "Collection", "Object"); - copyStruct("Set", "Collection", "Object"); - copyStruct("HashSet", "Set", "Collection", "Object"); - copyStruct("Set", "Collection", "Object"); - copyStruct("HashSet", "Set", "Collection", "Object"); - - copyStruct("Map", "Object"); - copyStruct("HashMap", "Map", "Object"); - copyStruct("Map", "Object"); - copyStruct("HashMap", "Map", "Object"); - copyStruct("Map", "Object"); - copyStruct("HashMap", "Map", "Object"); - copyStruct("Map", "Object"); - copyStruct("HashMap", "Map", "Object"); - - copyStruct("Executable", "Object"); - - copyStruct("Exception", "Object"); - copyStruct("ArithmeticException", "Exception", "Object"); - copyStruct("IllegalArgumentException", "Exception", "Object"); - copyStruct("IllegalStateException", "Exception", "Object"); - copyStruct("NumberFormatException", "Exception", "Object"); - - copyStruct("GeoPoint", "Object"); - copyStruct("Strings", "List", "Collection", "Object"); - copyStruct("Longs", "List", "Collection", "Object"); - copyStruct("Doubles", "List", "Collection", "Object"); - copyStruct("GeoPoints", "List", "Collection", "Object"); - - copyStruct("FeatureTest", "Object"); + int currentLine = -1; + try { + try (InputStream stream = Definition.class.getResourceAsStream("definition.txt"); + LineNumberReader reader = new LineNumberReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { + String line = null; + String currentClass = null; + while ((line = reader.readLine()) != null) { + currentLine = reader.getLineNumber(); + line = line.trim(); + if (line.length() == 0 || line.charAt(0) == '#') { + continue; + } else if (line.startsWith("class ")) { + assert currentClass == null; + currentClass = line.split("\u0020")[1]; + } else if (line.equals("}")) { + assert currentClass != null; + currentClass = null; + } else { + assert currentClass != null; + addSignature(currentClass, line); + } + } + } + } catch (Exception e) { + throw new RuntimeException("syntax error in definition line: " + currentLine, e); + } } private void addTransforms() { + Type booleanType = getType("boolean"); + Type objectType = getType("Object"); + Type defType = getType("def"); + Type booleanobjType = getType("Boolean"); + Type byteType = getType("byte"); + Type shortType = getType("short"); + Type intType = getType("int"); + Type charType = getType("char"); + Type longType = getType("long"); + Type floatType = getType("float"); + Type doubleType = getType("double"); + Type numberType = getType("Number"); + Type byteobjType = getType("Byte"); + Type shortobjType = getType("Short"); + Type charobjType = getType("Character"); + Type intobjType = getType("Integer"); + Type longobjType = getType("Long"); + Type floatobjType = getType("Float"); + Type doubleobjType = getType("Double"); + Type stringType = getType("String"); + addTransform(booleanType, objectType, "Boolean", "valueOf", true, false); addTransform(booleanType, defType, "Boolean", "valueOf", true, false); addTransform(booleanType, booleanobjType, "Boolean", "valueOf", true, false); @@ -1543,50 +811,6 @@ public final class Definition { addTransform(stringType, charobjType, "Utility", "StringToCharacter", true, true); } - private void addRuntimeClasses() { - addRuntimeClass(booleanType.struct); - addRuntimeClass(byteType.struct); - addRuntimeClass(shortType.struct); - addRuntimeClass(charType.struct); - addRuntimeClass(intType.struct); - addRuntimeClass(longType.struct); - addRuntimeClass(floatType.struct); - addRuntimeClass(doubleType.struct); - - addRuntimeClass(booleanobjType.struct); - addRuntimeClass(byteobjType.struct); - addRuntimeClass(shortobjType.struct); - addRuntimeClass(charobjType.struct); - addRuntimeClass(intobjType.struct); - addRuntimeClass(longobjType.struct); - addRuntimeClass(floatobjType.struct); - addRuntimeClass(doubleobjType.struct); - - addRuntimeClass(objectType.struct); - addRuntimeClass(numberType.struct); - addRuntimeClass(charseqType.struct); - addRuntimeClass(stringType.struct); - - addRuntimeClass(oitrType.struct); - addRuntimeClass(ocollectionType.struct); - addRuntimeClass(olistType.struct); - addRuntimeClass(oarraylistType.struct); - addRuntimeClass(osetType.struct); - addRuntimeClass(ohashsetType.struct); - addRuntimeClass(oomapType.struct); - addRuntimeClass(oohashmapType.struct); - - addRuntimeClass(exceptionType.struct); - - addRuntimeClass(geoPointType.struct); - addRuntimeClass(stringsType.struct); - addRuntimeClass(longsType.struct); - addRuntimeClass(doublesType.struct); - addRuntimeClass(geoPointsType.struct); - - addRuntimeClass(featureTestType.struct); - } - private final void addStruct(final String name, final Class clazz) { if (!name.matches("^[_a-zA-Z][<>,_a-zA-Z0-9]*$")) { throw new IllegalArgumentException("Invalid struct name [" + name + "]."); @@ -1599,9 +823,10 @@ public final class Definition { final Struct struct = new Struct(name, clazz, org.objectweb.asm.Type.getType(clazz)); structsMap.put(name, struct); + simpleTypesMap.put(name, getType(name)); } - - private final void addConstructor(final String struct, final String name, final Type[] args, final Type[] genargs) { + + private final void addConstructorInternal(final String struct, final String name, final Type[] args) { final Struct owner = structsMap.get(struct); if (owner == null) { @@ -1634,14 +859,6 @@ public final class Definition { final Class[] classes = new Class[args.length]; for (int count = 0; count < classes.length; ++count) { - if (genargs != null) { - if (!args[count].clazz.isAssignableFrom(genargs[count].clazz)) { - throw new ClassCastException("Generic argument [" + genargs[count].name + "]" + - " is not a sub class of [" + args[count].name + "] in the constructor" + - " [" + name + " ] from the struct [" + owner.name + "]."); - } - } - classes[count] = args[count].clazz; } @@ -1655,79 +872,96 @@ public final class Definition { } final org.objectweb.asm.commons.Method asm = org.objectweb.asm.commons.Method.getMethod(reflect); - final Constructor constructor = - new Constructor(name, owner, Arrays.asList(genargs != null ? genargs : args), asm, reflect); + final Constructor constructor = new Constructor(name, owner, Arrays.asList(args), asm, reflect); owner.constructors.put(methodKey, constructor); } + + /** + * Adds a new signature to the definition. + *

+ * Signatures have the following forms: + *

    + *
  • {@code void method(String,int)} + *
  • {@code boolean field} + *
  • {@code Class (String)} + *
+ * no spaces allowed. + */ + private final void addSignature(String className, String signature) { + String elements[] = signature.split("\u0020"); + if (elements.length != 2) { + throw new IllegalArgumentException("Malformed signature: " + signature); + } + // method or field type (e.g. return type) + Type rtn = getType(elements[0]); + int parenIndex = elements[1].indexOf('('); + if (parenIndex != -1) { + // method or ctor + int parenEnd = elements[1].indexOf(')'); + final Type args[]; + if (parenEnd > parenIndex + 1) { + String arguments[] = elements[1].substring(parenIndex + 1, parenEnd).split(","); + args = new Type[arguments.length]; + for (int i = 0; i < arguments.length; i++) { + args[i] = getType(arguments[i]); + } + } else { + args = new Type[0]; + } + String methodName = elements[1].substring(0, parenIndex); + if (methodName.equals("")) { + if (!elements[0].equals(className)) { + throw new IllegalArgumentException("Constructors must return their own type"); + } + addConstructorInternal(className, "new", args); + } else { + if (methodName.indexOf('/') >= 0) { + String nameAndAlias[] = methodName.split("/"); + if (nameAndAlias.length != 2) { + throw new IllegalArgumentException("Currently only two aliases are allowed!"); + } + addMethodInternal(className, nameAndAlias[0], nameAndAlias[1], rtn, args); + } else { + addMethodInternal(className, methodName, null, rtn, args); + } + } + } else { + // field + addFieldInternal(className, elements[1], null, rtn); + } + } - private final void addMethod(final String struct, final String name, final String alias, final boolean statik, - final Type rtn, final Type[] args, final Type genrtn, final Type[] genargs) { + private final void addMethodInternal(final String struct, final String name, final String alias, + final Type rtn, final Type[] args) { final Struct owner = structsMap.get(struct); if (owner == null) { throw new IllegalArgumentException("Owner struct [" + struct + "] not defined" + - " for " + (statik ? "function" : "method") + " [" + name + "]."); + " for method [" + name + "]."); } if (!name.matches("^[_a-zA-Z][_a-zA-Z0-9]*$")) { - throw new IllegalArgumentException("Invalid " + (statik ? "static method" : "method") + - " name [" + name + "] with the struct [" + owner.name + "]."); + throw new IllegalArgumentException("Invalid method name" + + " [" + name + "] with the struct [" + owner.name + "]."); } MethodKey methodKey = new MethodKey(name, args.length); if (owner.constructors.containsKey(methodKey)) { - throw new IllegalArgumentException("Constructors and " + (statik ? "static methods" : "methods") + + throw new IllegalArgumentException("Constructors and methods" + " may not have the same signature [" + methodKey + "] within the same struct" + " [" + owner.name + "]."); } - if (owner.staticMethods.containsKey(methodKey)) { - if (statik) { - throw new IllegalArgumentException( - "Duplicate static method signature [" + methodKey + "] found within the struct [" + owner.name + "]."); - } else { - throw new IllegalArgumentException("Static methods and methods may not have the same signature" + - " [" + methodKey + "] within the same struct [" + owner.name + "]."); - } - } - - if (owner.methods.containsKey(methodKey)) { - if (statik) { - throw new IllegalArgumentException("Static methods and methods may not have the same signature" + - " [" + methodKey + "] within the same struct [" + owner.name + "]."); - } else { - throw new IllegalArgumentException("Duplicate method signature [" + methodKey + "]" + - " found within the struct [" + owner.name + "]."); - } - } - - if (genrtn != null) { - if (!rtn.clazz.isAssignableFrom(genrtn.clazz)) { - throw new ClassCastException("Generic return [" + genrtn.clazz.getCanonicalName() + "]" + - " is not a sub class of [" + rtn.clazz.getCanonicalName() + "] in the method" + - " [" + name + " ] from the struct [" + owner.name + "]."); - } - } - - if (genargs != null && genargs.length != args.length) { - throw new IllegalArgumentException("Generic arguments arity [" + genargs.length + "] is not the same as " + - (statik ? "function" : "method") + " [" + name + "] arguments arity" + - " [" + args.length + "] within the struct [" + owner.name + "]."); + if (owner.staticMethods.containsKey(methodKey) || owner.methods.containsKey(methodKey)) { + throw new IllegalArgumentException( + "Duplicate method signature [" + methodKey + "] found within the struct [" + owner.name + "]."); } final Class[] classes = new Class[args.length]; for (int count = 0; count < classes.length; ++count) { - if (genargs != null) { - if (!args[count].clazz.isAssignableFrom(genargs[count].clazz)) { - throw new ClassCastException("Generic argument [" + genargs[count].name + "] is not a sub class" + - " of [" + args[count].name + "] in the " + (statik ? "function" : "method") + - " [" + name + " ] from the struct [" + owner.name + "]."); - } - } - classes[count] = args[count].clazz; } @@ -1736,15 +970,15 @@ public final class Definition { try { reflect = owner.clazz.getMethod(alias == null ? name : alias, classes); } catch (final NoSuchMethodException exception) { - throw new IllegalArgumentException((statik ? "Function" : "Method") + - " [" + (alias == null ? name : alias) + "] not found for class [" + owner.clazz.getName() + "]" + + throw new IllegalArgumentException("Method [" + (alias == null ? name : alias) + + "] not found for class [" + owner.clazz.getName() + "]" + " with arguments " + Arrays.toString(classes) + "."); } if (!reflect.getReturnType().equals(rtn.clazz)) { throw new IllegalArgumentException("Specified return type class [" + rtn.clazz + "]" + - " does not match the found return type class [" + reflect.getReturnType() + "] for the " + - (statik ? "function" : "method") + " [" + name + "]" + + " does not match the found return type class [" + reflect.getReturnType() + "] for the" + + " method [" + name + "]" + " within the struct [" + owner.name + "]."); } @@ -1760,67 +994,33 @@ public final class Definition { " with arguments " + Arrays.toString(classes) + "."); } - final Method method = new Method(name, owner, genrtn != null ? genrtn : rtn, - Arrays.asList(genargs != null ? genargs : args), asm, reflect, handle); + final Method method = new Method(name, owner, rtn, Arrays.asList(args), asm, reflect, handle); final int modifiers = reflect.getModifiers(); - if (statik) { - if (!java.lang.reflect.Modifier.isStatic(modifiers)) { - throw new IllegalArgumentException("Function [" + name + "]" + - " within the struct [" + owner.name + "] is not linked to a static Java method."); - } - + if (java.lang.reflect.Modifier.isStatic(modifiers)) { owner.staticMethods.put(methodKey, method); } else { - if (java.lang.reflect.Modifier.isStatic(modifiers)) { - throw new IllegalArgumentException("Method [" + name + "]" + - " within the struct [" + owner.name + "] is not linked to a non-static Java method."); - } - owner.methods.put(methodKey, method); } } - - private final void addField(final String struct, final String name, final String alias, - final boolean statik, final Type type, final Type generic) { + + private final void addFieldInternal(final String struct, final String name, final String alias, + final Type type) { final Struct owner = structsMap.get(struct); if (owner == null) { throw new IllegalArgumentException("Owner struct [" + struct + "] not defined for " + - (statik ? "static" : "member") + " [" + name + "]."); + " field [" + name + "]."); } if (!name.matches("^[_a-zA-Z][_a-zA-Z0-9]*$")) { - throw new IllegalArgumentException("Invalid " + (statik ? "static" : "member") + + throw new IllegalArgumentException("Invalid field " + " name [" + name + "] with the struct [" + owner.name + "]."); } - if (owner.staticMembers.containsKey(name)) { - if (statik) { - throw new IllegalArgumentException("Duplicate static name [" + name + "]" + - " found within the struct [" + owner.name + "]."); - } else { - throw new IllegalArgumentException("Statics and members may not have the same name " + - "[" + name + "] within the same struct [" + owner.name + "]."); - } - } - - if (owner.members.containsKey(name)) { - if (statik) { - throw new IllegalArgumentException("Statics and members may not have the same name " + - "[" + name + "] within the same struct [" + owner.name + "]."); - } else { - throw new IllegalArgumentException("Duplicate member name [" + name + "]" + - " found within the struct [" + owner.name + "]."); - } - } - - if (generic != null) { - if (!type.clazz.isAssignableFrom(generic.clazz)) { - throw new ClassCastException("Generic type [" + generic.clazz.getCanonicalName() + "]" + - " is not a sub class of [" + type.clazz.getCanonicalName() + "] for the field" + - " [" + name + " ] from the struct [" + owner.name + "]."); - } + if (owner.staticMembers.containsKey(name) || owner.members.containsKey(name)) { + throw new IllegalArgumentException("Duplicate field name [" + name + "]" + + " found within the struct [" + owner.name + "]."); } java.lang.reflect.Field reflect; @@ -1831,12 +1031,15 @@ public final class Definition { throw new IllegalArgumentException("Field [" + (alias == null ? name : alias) + "]" + " not found for class [" + owner.clazz.getName() + "]."); } + + final int modifiers = reflect.getModifiers(); + boolean isStatic = java.lang.reflect.Modifier.isStatic(modifiers); MethodHandle getter = null; MethodHandle setter = null; try { - if (!statik) { + if (!isStatic) { getter = MethodHandles.publicLookup().unreflectGetter(reflect); setter = MethodHandles.publicLookup().unreflectSetter(reflect); } @@ -1845,42 +1048,33 @@ public final class Definition { " not found for class [" + owner.clazz.getName() + "]."); } - final Field field = new Field(name, owner, generic == null ? type : generic, type, reflect, getter, setter); - final int modifiers = reflect.getModifiers(); - - if (statik) { - if (!java.lang.reflect.Modifier.isStatic(modifiers)) { - throw new IllegalArgumentException(); - } + final Field field = new Field(name, owner, type, type, reflect, getter, setter); + if (isStatic) { + // require that all static fields are static final if (!java.lang.reflect.Modifier.isFinal(modifiers)) { throw new IllegalArgumentException("Static [" + name + "]" + - " within the struct [" + owner.name + "] is not linked to static Java field."); + " within the struct [" + owner.name + "] is not final."); } owner.staticMembers.put(alias == null ? name : alias, field); } else { - if (java.lang.reflect.Modifier.isStatic(modifiers)) { - throw new IllegalArgumentException("Member [" + name + "]" + - " within the struct [" + owner.name + "] is not linked to non-static Java field."); - } - owner.members.put(alias == null ? name : alias, field); } } - private final void copyStruct(final String struct, final String... children) { + private final void copyStruct(final String struct, List children) { final Struct owner = structsMap.get(struct); if (owner == null) { throw new IllegalArgumentException("Owner struct [" + struct + "] not defined for copy."); } - for (int count = 0; count < children.length; ++count) { - final Struct child = structsMap.get(children[count]); + for (int count = 0; count < children.size(); ++count) { + final Struct child = structsMap.get(children.get(count)); if (struct == null) { - throw new IllegalArgumentException("Child struct [" + children[count] + "]" + + throw new IllegalArgumentException("Child struct [" + children.get(count) + "]" + " not defined for copy to owner struct [" + owner.name + "]."); } @@ -2133,6 +1327,11 @@ public final class Definition { } public final Type getType(final String name) { + // simple types (e.g. 0 array dimensions) are a simple hash lookup for speed + Type simple = simpleTypesMap.get(name); + if (simple != null) { + return simple; + } final int dimensions = getDimensions(name); final String structstr = dimensions == 0 ? name : name.substring(0, name.indexOf('[')); final Struct struct = structsMap.get(structstr); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java index fbb1d246a83..bb362558796 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java @@ -252,29 +252,29 @@ public final class MethodWriter extends GeneratorAdapter { switch (sort) { case INT: switch (operation) { - case MUL: invokeStatic(definition.mathType.type, MULEXACT_INT); break; - case DIV: invokeStatic(definition.utilityType.type, DIVWOOVERLOW_INT); break; - case ADD: invokeStatic(definition.mathType.type, ADDEXACT_INT); break; - case SUB: invokeStatic(definition.mathType.type, SUBEXACT_INT); break; + case MUL: invokeStatic(definition.getType("Math").type, MULEXACT_INT); break; + case DIV: invokeStatic(definition.getType("Utility").type, DIVWOOVERLOW_INT); break; + case ADD: invokeStatic(definition.getType("Math").type, ADDEXACT_INT); break; + case SUB: invokeStatic(definition.getType("Math").type, SUBEXACT_INT); break; } break; case LONG: switch (operation) { - case MUL: invokeStatic(definition.mathType.type, MULEXACT_LONG); break; - case DIV: invokeStatic(definition.utilityType.type, DIVWOOVERLOW_LONG); break; - case ADD: invokeStatic(definition.mathType.type, ADDEXACT_LONG); break; - case SUB: invokeStatic(definition.mathType.type, SUBEXACT_LONG); break; + case MUL: invokeStatic(definition.getType("Math").type, MULEXACT_LONG); break; + case DIV: invokeStatic(definition.getType("Utility").type, DIVWOOVERLOW_LONG); break; + case ADD: invokeStatic(definition.getType("Math").type, ADDEXACT_LONG); break; + case SUB: invokeStatic(definition.getType("Math").type, SUBEXACT_LONG); break; } break; case FLOAT: switch (operation) { - case MUL: invokeStatic(definition.utilityType.type, MULWOOVERLOW_FLOAT); break; - case DIV: invokeStatic(definition.utilityType.type, DIVWOOVERLOW_FLOAT); break; - case REM: invokeStatic(definition.utilityType.type, REMWOOVERLOW_FLOAT); break; - case ADD: invokeStatic(definition.utilityType.type, ADDWOOVERLOW_FLOAT); break; - case SUB: invokeStatic(definition.utilityType.type, SUBWOOVERLOW_FLOAT); break; + case MUL: invokeStatic(definition.getType("Utility").type, MULWOOVERLOW_FLOAT); break; + case DIV: invokeStatic(definition.getType("Utility").type, DIVWOOVERLOW_FLOAT); break; + case REM: invokeStatic(definition.getType("Utility").type, REMWOOVERLOW_FLOAT); break; + case ADD: invokeStatic(definition.getType("Utility").type, ADDWOOVERLOW_FLOAT); break; + case SUB: invokeStatic(definition.getType("Utility").type, SUBWOOVERLOW_FLOAT); break; default: throw new IllegalStateException("Error " + location + ": Illegal tree structure."); } @@ -282,11 +282,11 @@ public final class MethodWriter extends GeneratorAdapter { break; case DOUBLE: switch (operation) { - case MUL: invokeStatic(definition.utilityType.type, MULWOOVERLOW_DOUBLE); break; - case DIV: invokeStatic(definition.utilityType.type, DIVWOOVERLOW_DOUBLE); break; - case REM: invokeStatic(definition.utilityType.type, REMWOOVERLOW_DOUBLE); break; - case ADD: invokeStatic(definition.utilityType.type, ADDWOOVERLOW_DOUBLE); break; - case SUB: invokeStatic(definition.utilityType.type, SUBWOOVERLOW_DOUBLE); break; + case MUL: invokeStatic(definition.getType("Utility").type, MULWOOVERLOW_DOUBLE); break; + case DIV: invokeStatic(definition.getType("Utility").type, DIVWOOVERLOW_DOUBLE); break; + case REM: invokeStatic(definition.getType("Utility").type, REMWOOVERLOW_DOUBLE); break; + case ADD: invokeStatic(definition.getType("Utility").type, ADDWOOVERLOW_DOUBLE); break; + case SUB: invokeStatic(definition.getType("Utility").type, SUBWOOVERLOW_DOUBLE); break; default: throw new IllegalStateException("Error " + location + ": Illegal tree structure."); } @@ -305,17 +305,17 @@ public final class MethodWriter extends GeneratorAdapter { if (sort == Sort.DEF) { switch (operation) { - case MUL: invokeStatic(definition.defobjType.type, DEF_MUL_CALL); break; - case DIV: invokeStatic(definition.defobjType.type, DEF_DIV_CALL); break; - case REM: invokeStatic(definition.defobjType.type, DEF_REM_CALL); break; - case ADD: invokeStatic(definition.defobjType.type, DEF_ADD_CALL); break; - case SUB: invokeStatic(definition.defobjType.type, DEF_SUB_CALL); break; - case LSH: invokeStatic(definition.defobjType.type, DEF_LSH_CALL); break; - case USH: invokeStatic(definition.defobjType.type, DEF_RSH_CALL); break; - case RSH: invokeStatic(definition.defobjType.type, DEF_USH_CALL); break; - case BWAND: invokeStatic(definition.defobjType.type, DEF_AND_CALL); break; - case XOR: invokeStatic(definition.defobjType.type, DEF_XOR_CALL); break; - case BWOR: invokeStatic(definition.defobjType.type, DEF_OR_CALL); break; + case MUL: invokeStatic(definition.getType("Def").type, DEF_MUL_CALL); break; + case DIV: invokeStatic(definition.getType("Def").type, DEF_DIV_CALL); break; + case REM: invokeStatic(definition.getType("Def").type, DEF_REM_CALL); break; + case ADD: invokeStatic(definition.getType("Def").type, DEF_ADD_CALL); break; + case SUB: invokeStatic(definition.getType("Def").type, DEF_SUB_CALL); break; + case LSH: invokeStatic(definition.getType("Def").type, DEF_LSH_CALL); break; + case USH: invokeStatic(definition.getType("Def").type, DEF_RSH_CALL); break; + case RSH: invokeStatic(definition.getType("Def").type, DEF_USH_CALL); break; + case BWAND: invokeStatic(definition.getType("Def").type, DEF_AND_CALL); break; + case XOR: invokeStatic(definition.getType("Def").type, DEF_XOR_CALL); break; + case BWOR: invokeStatic(definition.getType("Def").type, DEF_OR_CALL); break; default: throw new IllegalStateException("Error " + location + ": Illegal tree structure."); } @@ -350,107 +350,107 @@ public final class MethodWriter extends GeneratorAdapter { final Definition definition, final Sort fsort, final Sort tsort) { if (fsort == Sort.DOUBLE) { if (tsort == Sort.FLOAT) { - invokeStatic(definition.utilityType.type, TOFLOATWOOVERFLOW_DOUBLE); + invokeStatic(definition.getType("Utility").type, TOFLOATWOOVERFLOW_DOUBLE); } else if (tsort == Sort.FLOAT_OBJ) { - invokeStatic(definition.utilityType.type, TOFLOATWOOVERFLOW_DOUBLE); - checkCast(definition.floatobjType.type); + invokeStatic(definition.getType("Utility").type, TOFLOATWOOVERFLOW_DOUBLE); + checkCast(definition.getType("Float").type); } else if (tsort == Sort.LONG) { - invokeStatic(definition.utilityType.type, TOLONGWOOVERFLOW_DOUBLE); + invokeStatic(definition.getType("Utility").type, TOLONGWOOVERFLOW_DOUBLE); } else if (tsort == Sort.LONG_OBJ) { - invokeStatic(definition.utilityType.type, TOLONGWOOVERFLOW_DOUBLE); - checkCast(definition.longobjType.type); + invokeStatic(definition.getType("Utility").type, TOLONGWOOVERFLOW_DOUBLE); + checkCast(definition.getType("Long").type); } else if (tsort == Sort.INT) { - invokeStatic(definition.utilityType.type, TOINTWOOVERFLOW_DOUBLE); + invokeStatic(definition.getType("Utility").type, TOINTWOOVERFLOW_DOUBLE); } else if (tsort == Sort.INT_OBJ) { - invokeStatic(definition.utilityType.type, TOINTWOOVERFLOW_DOUBLE); - checkCast(definition.intobjType.type); + invokeStatic(definition.getType("Utility").type, TOINTWOOVERFLOW_DOUBLE); + checkCast(definition.getType("Integer").type); } else if (tsort == Sort.CHAR) { - invokeStatic(definition.utilityType.type, TOCHARWOOVERFLOW_DOUBLE); + invokeStatic(definition.getType("Utility").type, TOCHARWOOVERFLOW_DOUBLE); } else if (tsort == Sort.CHAR_OBJ) { - invokeStatic(definition.utilityType.type, TOCHARWOOVERFLOW_DOUBLE); - checkCast(definition.charobjType.type); + invokeStatic(definition.getType("Utility").type, TOCHARWOOVERFLOW_DOUBLE); + checkCast(definition.getType("Character").type); } else if (tsort == Sort.SHORT) { - invokeStatic(definition.utilityType.type, TOSHORTWOOVERFLOW_DOUBLE); + invokeStatic(definition.getType("Utility").type, TOSHORTWOOVERFLOW_DOUBLE); } else if (tsort == Sort.SHORT_OBJ) { - invokeStatic(definition.utilityType.type, TOSHORTWOOVERFLOW_DOUBLE); - checkCast(definition.shortobjType.type); + invokeStatic(definition.getType("Utility").type, TOSHORTWOOVERFLOW_DOUBLE); + checkCast(definition.getType("Short").type); } else if (tsort == Sort.BYTE) { - invokeStatic(definition.utilityType.type, TOBYTEWOOVERFLOW_DOUBLE); + invokeStatic(definition.getType("Utility").type, TOBYTEWOOVERFLOW_DOUBLE); } else if (tsort == Sort.BYTE_OBJ) { - invokeStatic(definition.utilityType.type, TOBYTEWOOVERFLOW_DOUBLE); - checkCast(definition.byteobjType.type); + invokeStatic(definition.getType("Utility").type, TOBYTEWOOVERFLOW_DOUBLE); + checkCast(definition.getType("Byte").type); } else { return false; } } else if (fsort == Sort.FLOAT) { if (tsort == Sort.LONG) { - invokeStatic(definition.utilityType.type, TOLONGWOOVERFLOW_FLOAT); + invokeStatic(definition.getType("Utility").type, TOLONGWOOVERFLOW_FLOAT); } else if (tsort == Sort.LONG_OBJ) { - invokeStatic(definition.utilityType.type, TOLONGWOOVERFLOW_FLOAT); - checkCast(definition.longobjType.type); + invokeStatic(definition.getType("Utility").type, TOLONGWOOVERFLOW_FLOAT); + checkCast(definition.getType("Long").type); } else if (tsort == Sort.INT) { - invokeStatic(definition.utilityType.type, TOINTWOOVERFLOW_FLOAT); + invokeStatic(definition.getType("Utility").type, TOINTWOOVERFLOW_FLOAT); } else if (tsort == Sort.INT_OBJ) { - invokeStatic(definition.utilityType.type, TOINTWOOVERFLOW_FLOAT); - checkCast(definition.intobjType.type); + invokeStatic(definition.getType("Utility").type, TOINTWOOVERFLOW_FLOAT); + checkCast(definition.getType("Integer").type); } else if (tsort == Sort.CHAR) { - invokeStatic(definition.utilityType.type, TOCHARWOOVERFLOW_FLOAT); + invokeStatic(definition.getType("Utility").type, TOCHARWOOVERFLOW_FLOAT); } else if (tsort == Sort.CHAR_OBJ) { - invokeStatic(definition.utilityType.type, TOCHARWOOVERFLOW_FLOAT); - checkCast(definition.charobjType.type); + invokeStatic(definition.getType("Utility").type, TOCHARWOOVERFLOW_FLOAT); + checkCast(definition.getType("Character").type); } else if (tsort == Sort.SHORT) { - invokeStatic(definition.utilityType.type, TOSHORTWOOVERFLOW_FLOAT); + invokeStatic(definition.getType("Utility").type, TOSHORTWOOVERFLOW_FLOAT); } else if (tsort == Sort.SHORT_OBJ) { - invokeStatic(definition.utilityType.type, TOSHORTWOOVERFLOW_FLOAT); - checkCast(definition.shortobjType.type); + invokeStatic(definition.getType("Utility").type, TOSHORTWOOVERFLOW_FLOAT); + checkCast(definition.getType("Short").type); } else if (tsort == Sort.BYTE) { - invokeStatic(definition.utilityType.type, TOBYTEWOOVERFLOW_FLOAT); + invokeStatic(definition.getType("Utility").type, TOBYTEWOOVERFLOW_FLOAT); } else if (tsort == Sort.BYTE_OBJ) { - invokeStatic(definition.utilityType.type, TOBYTEWOOVERFLOW_FLOAT); - checkCast(definition.byteobjType.type); + invokeStatic(definition.getType("Utility").type, TOBYTEWOOVERFLOW_FLOAT); + checkCast(definition.getType("Byte").type); } else { return false; } } else if (fsort == Sort.LONG) { if (tsort == Sort.INT) { - invokeStatic(definition.mathType.type, TOINTEXACT_LONG); + invokeStatic(definition.getType("Math").type, TOINTEXACT_LONG); } else if (tsort == Sort.INT_OBJ) { - invokeStatic(definition.mathType.type, TOINTEXACT_LONG); - checkCast(definition.intobjType.type); + invokeStatic(definition.getType("Math").type, TOINTEXACT_LONG); + checkCast(definition.getType("Integer").type); } else if (tsort == Sort.CHAR) { - invokeStatic(definition.utilityType.type, TOCHAREXACT_LONG); + invokeStatic(definition.getType("Utility").type, TOCHAREXACT_LONG); } else if (tsort == Sort.CHAR_OBJ) { - invokeStatic(definition.utilityType.type, TOCHAREXACT_LONG); - checkCast(definition.charobjType.type); + invokeStatic(definition.getType("Utility").type, TOCHAREXACT_LONG); + checkCast(definition.getType("Character").type); } else if (tsort == Sort.SHORT) { - invokeStatic(definition.utilityType.type, TOSHORTEXACT_LONG); + invokeStatic(definition.getType("Utility").type, TOSHORTEXACT_LONG); } else if (tsort == Sort.SHORT_OBJ) { - invokeStatic(definition.utilityType.type, TOSHORTEXACT_LONG); - checkCast(definition.shortobjType.type); + invokeStatic(definition.getType("Utility").type, TOSHORTEXACT_LONG); + checkCast(definition.getType("Short").type); } else if (tsort == Sort.BYTE) { - invokeStatic(definition.utilityType.type, TOBYTEEXACT_LONG); + invokeStatic(definition.getType("Utility").type, TOBYTEEXACT_LONG); } else if (tsort == Sort.BYTE_OBJ) { - invokeStatic(definition.utilityType.type, TOBYTEEXACT_LONG); - checkCast(definition.byteobjType.type); + invokeStatic(definition.getType("Utility").type, TOBYTEEXACT_LONG); + checkCast(definition.getType("Byte").type); } else { return false; } } else if (fsort == Sort.INT) { if (tsort == Sort.CHAR) { - invokeStatic(definition.utilityType.type, TOCHAREXACT_INT); + invokeStatic(definition.getType("Utility").type, TOCHAREXACT_INT); } else if (tsort == Sort.CHAR_OBJ) { - invokeStatic(definition.utilityType.type, TOCHAREXACT_INT); - checkCast(definition.charobjType.type); + invokeStatic(definition.getType("Utility").type, TOCHAREXACT_INT); + checkCast(definition.getType("Character").type); } else if (tsort == Sort.SHORT) { - invokeStatic(definition.utilityType.type, TOSHORTEXACT_INT); + invokeStatic(definition.getType("Utility").type, TOSHORTEXACT_INT); } else if (tsort == Sort.SHORT_OBJ) { - invokeStatic(definition.utilityType.type, TOSHORTEXACT_INT); - checkCast(definition.shortobjType.type); + invokeStatic(definition.getType("Utility").type, TOSHORTEXACT_INT); + checkCast(definition.getType("Short").type); } else if (tsort == Sort.BYTE) { - invokeStatic(definition.utilityType.type, TOBYTEEXACT_INT); + invokeStatic(definition.getType("Utility").type, TOBYTEEXACT_INT); } else if (tsort == Sort.BYTE_OBJ) { - invokeStatic(definition.utilityType.type, TOBYTEEXACT_INT); - checkCast(definition.byteobjType.type); + invokeStatic(definition.getType("Utility").type, TOBYTEEXACT_INT); + checkCast(definition.getType("Byte").type); } else { return false; } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java index e5998948d62..de774344ee2 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java @@ -19,6 +19,7 @@ package org.elasticsearch.painless; + import org.elasticsearch.plugins.Plugin; import org.elasticsearch.script.ScriptEngineRegistry; import org.elasticsearch.script.ScriptMode; @@ -29,6 +30,16 @@ import org.elasticsearch.script.ScriptModule; */ public final class PainlessPlugin extends Plugin { + // parse our definition at startup (not on the user's first script) + // compilation process is sandboxed and has no file access. + static { + try { + Class.forName("org.elasticsearch.painless.Definition"); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + @Override public String name() { return "lang-painless"; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java index dafc6aaba8a..1d11dae720f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java @@ -38,9 +38,7 @@ import java.security.AccessController; import java.security.Permissions; import java.security.PrivilegedAction; import java.security.ProtectionDomain; -import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; /** diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Variables.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Variables.java index adf930b017c..d0b4d706f51 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Variables.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Variables.java @@ -101,35 +101,35 @@ public final class Variables { // Method variables. // This reference. Internal use only. - addVariable("[" + Reserved.THIS + "]" , definition.execType.name, Reserved.THIS , true, true); + addVariable("[" + Reserved.THIS + "]" , "Executable", Reserved.THIS , true, true); // Input map of variables passed to the script. TODO: Rename to 'params' since that will be its use. - addVariable("[" + Reserved.PARAMS + "]", definition.smapType.name, Reserved.PARAMS, true, true); + addVariable("[" + Reserved.PARAMS + "]", "Map", Reserved.PARAMS, true, true); // Scorer parameter passed to the script. Internal use only. - addVariable("[" + Reserved.SCORER + "]", definition.defType.name , Reserved.SCORER, true, true); + addVariable("[" + Reserved.SCORER + "]", "def", Reserved.SCORER, true, true); - // Doc parameter passed to the script. TODO: Currently working as a Map, we can do better? - addVariable("[" + Reserved.DOC + "]" , definition.smapType.name, Reserved.DOC , true, true); + // Doc parameter passed to the script. TODO: Currently working as a Map, we can do better? + addVariable("[" + Reserved.DOC + "]" , "Map", Reserved.DOC , true, true); // Aggregation _value parameter passed to the script. - addVariable("[" + Reserved.VALUE + "]" , definition.defType.name , Reserved.VALUE , true, true); + addVariable("[" + Reserved.VALUE + "]" , "def", Reserved.VALUE , true, true); // Shortcut variables. // Document's score as a read-only double. if (reserved.score) { - addVariable("[" + Reserved.SCORE + "]", definition.doubleType.name, Reserved.SCORE, true, true); + addVariable("[" + Reserved.SCORE + "]", "double", Reserved.SCORE, true, true); } // The ctx map set by executable scripts as a read-only map. if (reserved.ctx) { - addVariable("[" + Reserved.CTX + "]", definition.smapType.name, Reserved.CTX, true, true); + addVariable("[" + Reserved.CTX + "]", "Map", Reserved.CTX, true, true); } // Loop counter to catch infinite loops. Internal use only. if (reserved.loop && settings.getMaxLoopCounter() > 0) { - addVariable("[" + Reserved.LOOP + "]", definition.intType.name, Reserved.LOOP, true, true); + addVariable("[" + Reserved.LOOP + "]", "int", Reserved.LOOP, true, true); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java index 07fe1ff3447..18b9de80fb6 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java @@ -308,7 +308,7 @@ public final class EBinary extends AExpression { } left.expected = promote; - right.expected = definition.intType; + right.expected = definition.getType("int"); right.explicit = true; left = left.cast(settings, definition, variables); @@ -341,7 +341,7 @@ public final class EBinary extends AExpression { } left.expected = promote; - right.expected = definition.intType; + right.expected = definition.getType("int"); right.explicit = true; left = left.cast(settings, definition, variables); @@ -374,7 +374,7 @@ public final class EBinary extends AExpression { } left.expected = promote; - right.expected = definition.intType; + right.expected = definition.getType("int"); right.explicit = true; left = left.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java index 7f9f7dee000..4a6967c5285 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java @@ -45,11 +45,11 @@ public final class EBool extends AExpression { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.expected = definition.booleanType; + left.expected = definition.getType("boolean"); left.analyze(settings, definition, variables); left = left.cast(settings, definition, variables); - right.expected = definition.booleanType; + right.expected = definition.getType("boolean"); right.analyze(settings, definition, variables); right = right.cast(settings, definition, variables); @@ -63,7 +63,7 @@ public final class EBool extends AExpression { } } - actual = definition.booleanType; + actual = definition.getType("boolean"); } @Override diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java index 9b9f0917546..631b47db5d1 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java @@ -37,7 +37,7 @@ public final class EBoolean extends AExpression { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - actual = definition.booleanType; + actual = definition.getType("boolean"); } @Override diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java index 39afcd935ad..763005d17ba 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java @@ -200,7 +200,7 @@ public final class EChain extends AExpression { expression.expected = expression.actual; } else if (operation == Operation.LSH || operation == Operation.RSH || operation == Operation.USH) { - expression.expected = definition.intType; + expression.expected = definition.getType("int"); expression.explicit = true; } else { expression.expected = promote; @@ -215,7 +215,7 @@ public final class EChain extends AExpression { back = AnalyzerCaster.getLegalCast(definition, location, promote, last.after, true); this.statement = true; - this.actual = read ? last.after : definition.voidType; + this.actual = read ? last.after : definition.getType("void"); } private void analyzeWrite(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -235,7 +235,7 @@ public final class EChain extends AExpression { expression = expression.cast(settings, definition, variables); this.statement = true; - this.actual = read ? last.after : definition.voidType; + this.actual = read ? last.after : definition.getType("void"); } private void analyzeRead() { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java index d9337ae562b..a65e82e02fa 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java @@ -119,7 +119,7 @@ public final class EComp extends AExpression { } } - actual = definition.booleanType; + actual = definition.getType("boolean"); } private void analyzeEqR(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -161,7 +161,7 @@ public final class EComp extends AExpression { } } - actual = definition.booleanType; + actual = definition.getType("boolean"); } private void analyzeNE(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -207,7 +207,7 @@ public final class EComp extends AExpression { } } - actual = definition.booleanType; + actual = definition.getType("boolean"); } private void analyzeNER(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -249,7 +249,7 @@ public final class EComp extends AExpression { } } - actual = definition.booleanType; + actual = definition.getType("boolean"); } private void analyzeGTE(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -285,7 +285,7 @@ public final class EComp extends AExpression { } } - actual = definition.booleanType; + actual = definition.getType("boolean"); } private void analyzeGT(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -321,7 +321,7 @@ public final class EComp extends AExpression { } } - actual = definition.booleanType; + actual = definition.getType("boolean"); } private void analyzeLTE(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -357,7 +357,7 @@ public final class EComp extends AExpression { } } - actual = definition.booleanType; + actual = definition.getType("boolean"); } private void analyzeLT(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -393,7 +393,7 @@ public final class EComp extends AExpression { } } - actual = definition.booleanType; + actual = definition.getType("boolean"); } @Override @@ -456,7 +456,7 @@ public final class EComp extends AExpression { if (right.isNull) { adapter.ifNull(jump); } else if (!left.isNull && operation == Operation.EQ) { - adapter.invokeStatic(definition.defobjType.type, DEF_EQ_CALL); + adapter.invokeStatic(definition.getType("Def").type, DEF_EQ_CALL); } else { adapter.ifCmp(rtype, MethodWriter.EQ, jump); } @@ -464,19 +464,19 @@ public final class EComp extends AExpression { if (right.isNull) { adapter.ifNonNull(jump); } else if (!left.isNull && operation == Operation.NE) { - adapter.invokeStatic(definition.defobjType.type, DEF_EQ_CALL); + adapter.invokeStatic(definition.getType("Def").type, DEF_EQ_CALL); adapter.ifZCmp(MethodWriter.EQ, jump); } else { adapter.ifCmp(rtype, MethodWriter.NE, jump); } } else if (lt) { - adapter.invokeStatic(definition.defobjType.type, DEF_LT_CALL); + adapter.invokeStatic(definition.getType("Def").type, DEF_LT_CALL); } else if (lte) { - adapter.invokeStatic(definition.defobjType.type, DEF_LTE_CALL); + adapter.invokeStatic(definition.getType("Def").type, DEF_LTE_CALL); } else if (gt) { - adapter.invokeStatic(definition.defobjType.type, DEF_GT_CALL); + adapter.invokeStatic(definition.getType("Def").type, DEF_GT_CALL); } else if (gte) { - adapter.invokeStatic(definition.defobjType.type, DEF_GTE_CALL); + adapter.invokeStatic(definition.getType("Def").type, DEF_GTE_CALL); } else { throw new IllegalStateException(error("Illegal tree structure.")); } @@ -493,7 +493,7 @@ public final class EComp extends AExpression { if (right.isNull) { adapter.ifNull(jump); } else if (operation == Operation.EQ) { - adapter.invokeStatic(definition.utilityType.type, CHECKEQUALS); + adapter.invokeStatic(definition.getType("Utility").type, CHECKEQUALS); if (branch) { adapter.ifZCmp(MethodWriter.NE, jump); @@ -507,7 +507,7 @@ public final class EComp extends AExpression { if (right.isNull) { adapter.ifNonNull(jump); } else if (operation == Operation.NE) { - adapter.invokeStatic(definition.utilityType.type, CHECKEQUALS); + adapter.invokeStatic(definition.getType("Utility").type, CHECKEQUALS); adapter.ifZCmp(MethodWriter.EQ, jump); } else { adapter.ifCmp(rtype, MethodWriter.NE, jump); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java index 5853fa3242e..45976c13414 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java @@ -47,7 +47,7 @@ public final class EConditional extends AExpression { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - condition.expected = definition.booleanType; + condition.expected = definition.getType("boolean"); condition.analyze(settings, definition, variables); condition = condition.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java index 7afa88ffc9a..f0ee3a8de51 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java @@ -40,23 +40,23 @@ final class EConstant extends AExpression { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { if (constant instanceof String) { - actual = definition.stringType; + actual = definition.getType("String"); } else if (constant instanceof Double) { - actual = definition.doubleType; + actual = definition.getType("double"); } else if (constant instanceof Float) { - actual = definition.floatType; + actual = definition.getType("float"); } else if (constant instanceof Long) { - actual = definition.longType; + actual = definition.getType("long"); } else if (constant instanceof Integer) { - actual = definition.intType; + actual = definition.getType("int"); } else if (constant instanceof Character) { - actual = definition.charType; + actual = definition.getType("char"); } else if (constant instanceof Short) { - actual = definition.shortType; + actual = definition.getType("short"); } else if (constant instanceof Byte) { - actual = definition.byteType; + actual = definition.getType("byte"); } else if (constant instanceof Boolean) { - actual = definition.booleanType; + actual = definition.getType("boolean"); } else { throw new IllegalStateException(error("Illegal tree structure.")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java index 7583d3eb158..9019d370895 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java @@ -42,14 +42,14 @@ 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.floatType; + actual = definition.getType("float"); } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid float constant [" + value + "].")); } } else { try { constant = Double.parseDouble(value); - actual = definition.doubleType; + actual = definition.getType("double"); } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid double constant [" + value + "].")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java index 0c8500c528b..7098e583c5a 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java @@ -45,7 +45,7 @@ public final class ENull extends AExpression { actual = expected; } else { - actual = definition.objectType; + actual = definition.getType("Object"); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java index ed7314b3571..489334ae24e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java @@ -49,7 +49,7 @@ public final class ENumeric extends AExpression { try { constant = Double.parseDouble(value.substring(0, value.length() - 1)); - actual = definition.doubleType; + actual = definition.getType("double"); } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid double constant [" + value + "].")); } @@ -60,14 +60,14 @@ public final class ENumeric extends AExpression { try { constant = Float.parseFloat(value.substring(0, value.length() - 1)); - actual = definition.floatType; + actual = definition.getType("float"); } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("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.longType; + actual = definition.getType("long"); } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid long constant [" + value + "].")); } @@ -78,16 +78,16 @@ public final class ENumeric extends AExpression { if (sort == Sort.BYTE && integer >= Byte.MIN_VALUE && integer <= Byte.MAX_VALUE) { constant = (byte)integer; - actual = definition.byteType; + actual = definition.getType("byte"); } else if (sort == Sort.CHAR && integer >= Character.MIN_VALUE && integer <= Character.MAX_VALUE) { constant = (char)integer; - actual = definition.charType; + actual = definition.getType("char"); } else if (sort == Sort.SHORT && integer >= Short.MIN_VALUE && integer <= Short.MAX_VALUE) { constant = (short)integer; - actual = definition.shortType; + actual = definition.getType("short"); } else { constant = integer; - actual = definition.intType; + actual = definition.getType("int"); } } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid int constant [" + value + "].")); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java index f4205223a65..cbf76373136 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java @@ -65,7 +65,7 @@ public final class EUnary extends AExpression { } void analyzeNot(final CompilerSettings settings, final Definition definition, final Variables variables) { - child.expected = definition.booleanType; + child.expected = definition.getType("boolean"); child.analyze(settings, definition, variables); child = child.cast(settings, definition, variables); @@ -73,7 +73,7 @@ public final class EUnary extends AExpression { constant = !(boolean)child.constant; } - actual = definition.booleanType; + actual = definition.getType("boolean"); } void analyzeBWNot(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -195,7 +195,7 @@ public final class EUnary extends AExpression { if (operation == Operation.BWNOT) { if (sort == Sort.DEF) { - adapter.invokeStatic(definition.defobjType.type, DEF_NOT_CALL); + adapter.invokeStatic(definition.getType("Def").type, DEF_NOT_CALL); } else { if (sort == Sort.INT) { adapter.push(-1); @@ -209,15 +209,15 @@ public final class EUnary extends AExpression { } } else if (operation == Operation.SUB) { if (sort == Sort.DEF) { - adapter.invokeStatic(definition.defobjType.type, DEF_NEG_CALL); + adapter.invokeStatic(definition.getType("Def").type, DEF_NEG_CALL); } else { if (settings.getNumericOverflow()) { adapter.math(MethodWriter.NEG, type); } else { if (sort == Sort.INT) { - adapter.invokeStatic(definition.mathType.type, NEGATEEXACT_INT); + adapter.invokeStatic(definition.getType("Math").type, NEGATEEXACT_INT); } else if (sort == Sort.LONG) { - adapter.invokeStatic(definition.mathType.type, NEGATEEXACT_LONG); + adapter.invokeStatic(definition.getType("Math").type, NEGATEEXACT_LONG); } else { throw new IllegalStateException(error("Illegal tree structure.")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java index 5803fcfa273..d41128f60bb 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java @@ -46,7 +46,7 @@ public final class LArrayLength extends ALink { throw new IllegalArgumentException(error("Cannot write to read-only array field [length].")); } - after = definition.intType; + after = definition.getType("int"); } else { throw new IllegalArgumentException(error("Illegal field access [" + value + "].")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java index b38826f9e7e..1e38161ae87 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java @@ -50,7 +50,7 @@ public final class LBrace extends ALink { final Sort sort = before.sort; if (sort == Sort.ARRAY) { - index.expected = definition.intType; + index.expected = definition.getType("int"); index.analyze(settings, definition, variables); index = index.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java index 98b2fbe7bf9..68f60ef6f8f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java @@ -47,7 +47,7 @@ final class LDefArray extends ALink implements IDefLink { index.expected = index.actual; index = index.cast(settings, definition, variables); - after = definition.defType; + after = definition.getType("def"); return this; } @@ -59,13 +59,13 @@ final class LDefArray extends ALink implements IDefLink { @Override void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { - final String desc = Type.getMethodDescriptor(after.type, definition.defType.type, index.actual.type); + final String desc = Type.getMethodDescriptor(after.type, definition.getType("def").type, index.actual.type); adapter.invokeDynamic("arrayLoad", desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.ARRAY_LOAD); } @Override void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { - final String desc = Type.getMethodDescriptor(definition.voidType.type, definition.defType.type, + final String desc = Type.getMethodDescriptor(definition.getType("void").type, definition.getType("def").type, index.actual.type, after.type); adapter.invokeDynamic("arrayStore", desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.ARRAY_STORE); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java index 9dbe65110ee..1285d548163 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java @@ -55,7 +55,7 @@ final class LDefCall extends ALink implements IDefLink { } statement = true; - after = definition.defType; + after = definition.getType("def"); return this; } @@ -71,7 +71,7 @@ final class LDefCall extends ALink implements IDefLink { signature.append('('); // first parameter is the receiver, we never know its type: always Object - signature.append(definition.defType.type.getDescriptor()); + signature.append(definition.getType("def").type.getDescriptor()); // TODO: remove our explicit conversions and feed more type information for return value, // it can avoid some unnecessary boxing etc. diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java index 759b407cb5a..9dbe1cc3367 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java @@ -44,7 +44,7 @@ final class LDefField extends ALink implements IDefLink { @Override ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - after = definition.defType; + after = definition.getType("def"); return this; } @@ -56,13 +56,13 @@ final class LDefField extends ALink implements IDefLink { @Override void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { - final String desc = Type.getMethodDescriptor(after.type, definition.defType.type); + final String desc = Type.getMethodDescriptor(after.type, definition.getType("def").type); adapter.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.LOAD); } @Override void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { - final String desc = Type.getMethodDescriptor(definition.voidType.type, definition.defType.type, after.type); + final String desc = Type.getMethodDescriptor(definition.getType("void").type, definition.getType("def").type, after.type); adapter.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.STORE); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java index 8526ef1297e..f1649f3bf37 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java @@ -61,7 +61,7 @@ final class LListShortcut extends ALink { } if ((load || store) && (!load || getter != null) && (!store || setter != null)) { - index.expected = definition.intType; + index.expected = definition.getType("int"); index.analyze(settings, definition, variables); index = index.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java index 67f9769bd6a..acafc44ede1 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java @@ -63,7 +63,7 @@ public final class LNewArray extends ALink { for (int argument = 0; argument < arguments.size(); ++argument) { final AExpression expression = arguments.get(argument); - expression.expected = definition.intType; + expression.expected = definition.getType("int"); expression.analyze(settings, definition, variables); arguments.set(argument, expression.cast(settings, definition, variables)); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java index 1d11652f483..6b91cf5e87a 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java @@ -45,7 +45,7 @@ public final class LString extends ALink { throw new IllegalArgumentException(error("Must read String constant [" + string + "].")); } - after = definition.stringType; + after = definition.getType("String"); return this; } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java index 63d3df4bcee..7a79fe9c02c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java @@ -53,7 +53,7 @@ public final class SDo extends AStatement { throw new IllegalArgumentException(error("Extraneous do while loop.")); } - condition.expected = definition.booleanType; + condition.expected = definition.getType("boolean"); condition.analyze(settings, definition, variables); condition = condition.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java index dd7cffaa970..39ab0c099a6 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java @@ -49,7 +49,7 @@ public final class SExpression extends AStatement { final boolean rtn = lastSource && expression.actual.sort != Sort.VOID; - expression.expected = rtn ? definition.objectType : expression.actual; + expression.expected = rtn ? definition.getType("Object") : expression.actual; expression = expression.cast(settings, definition, variables); methodEscape = rtn; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java index 43c978b47fa..239e302c72d 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java @@ -70,7 +70,7 @@ public final class SFor extends AStatement { if (condition != null) { - condition.expected = definition.booleanType; + condition.expected = definition.getType("boolean"); condition.analyze(settings, definition, variables); condition = condition.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java index 698d8c8126c..89dad5a96c4 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java @@ -45,7 +45,7 @@ public final class SIfElse extends AStatement { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - condition.expected = definition.booleanType; + condition.expected = definition.getType("boolean"); condition.analyze(settings, definition, variables); condition = condition.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java index b959b47a96b..68084a9a70c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java @@ -39,7 +39,7 @@ public final class SReturn extends AStatement { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - expression.expected = definition.objectType; + expression.expected = definition.getType("Object"); expression.analyze(settings, definition, variables); expression = expression.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java index eac039b998e..b840fce3a83 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java @@ -39,7 +39,7 @@ public final class SThrow extends AStatement { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - expression.expected = definition.exceptionType; + expression.expected = definition.getType("Exception"); expression.analyze(settings, definition, variables); expression = expression.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java index f6f8ddc678f..5cabb1b0f7c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java @@ -44,7 +44,7 @@ public final class SWhile extends AStatement { void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { variables.incrementScope(); - condition.expected = definition.booleanType; + condition.expected = definition.getType("boolean"); condition.analyze(settings, definition, variables); condition = condition.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/definition.txt b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/definition.txt new file mode 100644 index 00000000000..4ca37223043 --- /dev/null +++ b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/definition.txt @@ -0,0 +1,529 @@ +# +# Licensed to Elasticsearch under one or more contributor +# license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright +# ownership. Elasticsearch licenses this file to you under +# the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +# +# Painless definition file. This defines the hierarchy of classes, +# what methods and fields they have, etc. +# + +# primitive types + +class void -> void { +} + +class boolean -> boolean { +} + +class byte -> byte { +} + +class short -> short { +} + +class char -> char { +} + +class int -> int { +} + +class long -> long { +} + +class float -> float { +} + +class double -> double { +} + +# basic JDK classes + +class Object -> java.lang.Object { + boolean equals(Object) + int hashCode() + String toString() +} + +class def -> java.lang.Object { + boolean equals(Object) + int hashCode() + String toString() +} + +class Void -> java.lang.Void extends Object { +} + +class Boolean -> java.lang.Boolean extends Object { + Boolean (boolean) + Boolean TRUE + Boolean FALSE + int compare(boolean,boolean) + boolean parseBoolean(String) + Boolean valueOf(boolean) + boolean booleanValue() + int compareTo(Boolean) +} + +class Byte -> java.lang.Byte extends Number,Object { + Byte (byte) + byte MIN_VALUE + byte MAX_VALUE + int compare(byte,byte) + int compareTo(Byte) + byte parseByte(String) + Byte valueOf(byte) +} + +class Short -> java.lang.Short extends Number,Object { + Short (short) + short MIN_VALUE + short MAX_VALUE + int compare(short,short) + int compareTo(Short) + short parseShort(String) + Short valueOf(short) +} + +class Character -> java.lang.Character extends Object { + Character (char) + char MIN_VALUE + char MAX_VALUE + int charCount(int) + char charValue() + int compare(char,char) + int compareTo(Character) + int digit(int,int) + char forDigit(int,int) + String getName(int) + int getNumericValue(int) + boolean isAlphabetic(int) + boolean isDefined(int) + boolean isDigit(int) + boolean isIdeographic(int) + boolean isLetter(int) + boolean isLetterOrDigit(int) + boolean isLowerCase(int) + boolean isMirrored(int) + boolean isSpaceChar(int) + boolean isTitleCase(int) + boolean isUpperCase(int) + boolean isWhitespace(int) + Character valueOf(char) +} + +class Integer -> java.lang.Integer extends Number,Object { + Integer (int) + int MIN_VALUE + int MAX_VALUE + int compare(int,int) + int compareTo(Integer) + int min(int,int) + int max(int,int) + int parseInt(String) + int signum(int) + String toHexString(int) + Integer valueOf(int) +} + +class Long -> java.lang.Long extends Number,Object { + Long (long) + long MIN_VALUE + long MAX_VALUE + int compare(long,long) + int compareTo(Long) + long min(long,long) + long max(long,long) + long parseLong(String) + int signum(long) + String toHexString(long) + Long valueOf(long) +} + +class Float -> java.lang.Float extends Number,Object { + Float (float) + float MIN_VALUE + float MAX_VALUE + int compare(float,float) + int compareTo(Float) + float min(float,float) + float max(float,float) + float parseFloat(String) + String toHexString(float) + Float valueOf(float) +} + +class Double -> java.lang.Double extends Number,Object { + Double (double) + double MIN_VALUE + double MAX_VALUE + int compare(double,double) + int compareTo(Double) + double min(double,double) + double max(double,double) + double parseDouble(String) + String toHexString(double) + Double valueOf(double) +} + +class Number -> java.lang.Number extends Object { + byte byteValue() + short shortValue() + int intValue() + long longValue() + float floatValue() + double doubleValue() +} + +class CharSequence -> java.lang.CharSequence extends Object { + char charAt(int) + int length() +} + +class String -> java.lang.String extends CharSequence,Object { + String () + int codePointAt(int) + int compareTo(String) + String concat(String) + boolean endsWith(String) + int indexOf(String) + int indexOf(String,int) + boolean isEmpty() + String replace(CharSequence,CharSequence) + boolean startsWith(String) + String substring(int,int) + char[] toCharArray() + String trim() +} + +class Math -> java.lang.Math { + double E + double PI + double abs(double) + double acos(double) + double asin(double) + double atan(double) + double atan2(double,double) + double cbrt(double) + double ceil(double) + double cos(double) + double cosh(double) + double exp(double) + double expm1(double) + double floor(double) + double hypot(double,double) + double log(double) + double log10(double) + double log1p(double) + double max(double,double) + double min(double,double) + double pow(double,double) + double random() + double rint(double) + long round(double) + double sin(double) + double sinh(double) + double sqrt(double) + double tan(double) + double tanh(double) + double toDegrees(double) + double toRadians(double) +} + +class Iterator -> java.util.Iterator extends Object { + boolean hasNext() + def next() + void remove() +} + +class Collection -> java.util.Collection extends Object { + boolean add(def) + void clear() + boolean contains(def) + boolean isEmpty() + Iterator iterator() + boolean remove(def) + int size() +} + +class List -> java.util.List extends Collection,Object { + def set(int,def) + def get(int) + def remove(int) + int getLength/size() +} + +class ArrayList -> java.util.ArrayList extends List,Collection,Object { + ArrayList () +} + +class Set -> java.util.Set extends Collection,Object { +} + +class HashSet -> java.util.HashSet extends Set,Collection,Object { + HashSet () +} + +class Map -> java.util.Map extends Object { + def put(def,def) + def get(def) + def remove(def) + boolean isEmpty() + int size() + boolean containsKey(def) + Set keySet() + Collection values() +} + +class HashMap -> java.util.HashMap extends Map,Object { + HashMap () +} + +class Exception -> java.lang.Exception extends Object { + String getMessage() +} + +class ArithmeticException -> java.lang.ArithmeticException extends Exception,Object { + ArithmeticException () +} + +class IllegalArgumentException -> java.lang.IllegalArgumentException extends Exception,Object { + IllegalArgumentException () +} + +class IllegalStateException -> java.lang.IllegalStateException extends Exception,Object { + IllegalStateException () +} + +class NumberFormatException -> java.lang.NumberFormatException extends Exception,Object { + NumberFormatException () +} + +# ES Scripting API + +class GeoPoint -> org.elasticsearch.common.geo.GeoPoint extends Object { + double getLat() + double getLon() +} + +class Strings -> org.elasticsearch.index.fielddata.ScriptDocValues$Strings extends List,Collection,Object { + String getValue() + List getValues() +} + +class Longs -> org.elasticsearch.index.fielddata.ScriptDocValues$Longs extends List,Collection,Object { + long getValue() + List getValues() +} + +class Doubles -> org.elasticsearch.index.fielddata.ScriptDocValues$Doubles extends List,Collection,Object { + double getValue() + List getValues() +} + +class GeoPoints -> org.elasticsearch.index.fielddata.ScriptDocValues$GeoPoints extends List,Collection,Object { + GeoPoint getValue() + List getValues() + double getLat() + double getLon() + double[] getLats() + double[] getLons() + + # geo distance functions... so many... + double factorDistance(double,double) + double factorDistanceWithDefault(double,double,double) + double factorDistance02(double,double) + double factorDistance13(double,double) + double arcDistance(double,double) + double arcDistanceWithDefault(double,double,double) + double arcDistanceInKm(double,double) + double arcDistanceInKmWithDefault(double,double,double) + double arcDistanceInMiles(double,double) + double arcDistanceInMilesWithDefault(double,double,double) + double distance(double,double) + double distanceWithDefault(double,double,double) + double distanceInKm(double,double) + double distanceInKmWithDefault(double,double,double) + double distanceInMiles(double,double) + double distanceInMilesWithDefault(double,double,double) + double geohashDistance(String) + double geohashDistanceInKm(String) + double geohashDistanceInMiles(String) +} + +# internal conversion methods +class Utility -> org.elasticsearch.painless.Utility { + boolean NumberToboolean(Number) + char NumberTochar(Number) + Boolean NumberToBoolean(Number) + Byte NumberToByte(Number) + Short NumberToShort(Number) + Character NumberToCharacter(Number) + Integer NumberToInteger(Number) + Long NumberToLong(Number) + Float NumberToFloat(Number) + Double NumberToDouble(Number) + byte booleanTobyte(boolean) + short booleanToshort(boolean) + char booleanTochar(boolean) + int booleanToint(boolean) + long booleanTolong(boolean) + float booleanTofloat(boolean) + double booleanTodouble(boolean) + Integer booleanToInteger(boolean) + byte BooleanTobyte(Boolean) + short BooleanToshort(Boolean) + char BooleanTochar(Boolean) + int BooleanToint(Boolean) + long BooleanTolong(Boolean) + float BooleanTofloat(Boolean) + double BooleanTodouble(Boolean) + Byte BooleanToByte(Boolean) + Short BooleanToShort(Boolean) + Character BooleanToCharacter(Boolean) + Integer BooleanToInteger(Boolean) + Long BooleanToLong(Boolean) + Float BooleanToFloat(Boolean) + Double BooleanToDouble(Boolean) + boolean byteToboolean(byte) + Short byteToShort(byte) + Character byteToCharacter(byte) + Integer byteToInteger(byte) + Long byteToLong(byte) + Float byteToFloat(byte) + Double byteToDouble(byte) + boolean ByteToboolean(Byte) + char ByteTochar(Byte) + boolean shortToboolean(short) + Byte shortToByte(short) + Character shortToCharacter(short) + Integer shortToInteger(short) + Long shortToLong(short) + Float shortToFloat(short) + Double shortToDouble(short) + boolean ShortToboolean(Short) + char ShortTochar(Short) + boolean charToboolean(char) + Byte charToByte(char) + Short charToShort(char) + Integer charToInteger(char) + Long charToLong(char) + Float charToFloat(char) + Double charToDouble(char) + String charToString(char) + boolean CharacterToboolean(Character) + byte CharacterTobyte(Character) + short CharacterToshort(Character) + int CharacterToint(Character) + long CharacterTolong(Character) + float CharacterTofloat(Character) + double CharacterTodouble(Character) + Boolean CharacterToBoolean(Character) + Byte CharacterToByte(Character) + Short CharacterToShort(Character) + Integer CharacterToInteger(Character) + Long CharacterToLong(Character) + Float CharacterToFloat(Character) + Double CharacterToDouble(Character) + String CharacterToString(Character) + boolean intToboolean(int) + Byte intToByte(int) + Short intToShort(int) + Character intToCharacter(int) + Long intToLong(int) + Float intToFloat(int) + Double intToDouble(int) + boolean IntegerToboolean(Integer) + char IntegerTochar(Integer) + boolean longToboolean(long) + Byte longToByte(long) + Short longToShort(long) + Character longToCharacter(long) + Integer longToInteger(long) + Float longToFloat(long) + Double longToDouble(long) + boolean LongToboolean(Long) + char LongTochar(Long) + boolean floatToboolean(float) + Byte floatToByte(float) + Short floatToShort(float) + Character floatToCharacter(float) + Integer floatToInteger(float) + Long floatToLong(float) + Double floatToDouble(float) + boolean FloatToboolean(Float) + char FloatTochar(Float) + boolean doubleToboolean(double) + Byte doubleToByte(double) + Short doubleToShort(double) + Character doubleToCharacter(double) + Integer doubleToInteger(double) + Long doubleToLong(double) + Float doubleToFloat(double) + boolean DoubleToboolean(Double) + char DoubleTochar(Double) + char StringTochar(String) + Character StringToCharacter(String) +} + +class Def -> org.elasticsearch.painless.Def { + byte DefTobyteImplicit(def) + short DefToshortImplicit(def) + char DefTocharImplicit(def) + int DefTointImplicit(def) + long DefTolongImplicit(def) + float DefTofloatImplicit(def) + double DefTodoubleImplicit(def) + Byte DefToByteImplicit(def) + Short DefToShortImplicit(def) + Character DefToCharacterImplicit(def) + Integer DefToIntegerImplicit(def) + Long DefToLongImplicit(def) + Float DefToFloatImplicit(def) + Double DefToDoubleImplicit(def) + byte DefTobyteExplicit(def) + short DefToshortExplicit(def) + char DefTocharExplicit(def) + int DefTointExplicit(def) + long DefTolongExplicit(def) + float DefTofloatExplicit(def) + double DefTodoubleExplicit(def) + Byte DefToByteExplicit(def) + Short DefToShortExplicit(def) + Character DefToCharacterExplicit(def) + Integer DefToIntegerExplicit(def) + Long DefToLongExplicit(def) + Float DefToFloatExplicit(def) + Double DefToDoubleExplicit(def) +} + +# for testing. +# currently FeatureTest exposes overloaded constructor, field load store, and overloaded static methods +class FeatureTest -> org.elasticsearch.painless.FeatureTest extends Object { + FeatureTest () + FeatureTest (int,int) + int getX() + int getY() + void setX(int) + void setY(int) + boolean overloadedStatic() + boolean overloadedStatic(boolean) +} + +# currently needed internally +class Executable -> org.elasticsearch.painless.Executable { +} diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicAPITests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicAPITests.java index af067d15252..b7479b505fe 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicAPITests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicAPITests.java @@ -24,10 +24,8 @@ public class BasicAPITests extends ScriptTestCase { public void testListIterator() { assertEquals(3, exec("List x = new ArrayList(); x.add(2); x.add(3); x.add(-2); Iterator y = x.iterator(); " + "int total = 0; while (y.hasNext()) total += y.next(); return total;")); - assertEquals(3, exec("List x = new ArrayList(); x.add(2); x.add(3); x.add(-2); Iterator y = x.iterator(); " + - "int total = 0; while (y.hasNext()) total += (int)y.next(); return total;")); - assertEquals("abc", exec("List x = new ArrayList(); x.add(\"a\"); x.add(\"b\"); x.add(\"c\"); " + - "Iterator y = x.iterator(); String total = \"\"; while (y.hasNext()) total += y.next(); return total;")); + assertEquals("abc", exec("List x = new ArrayList(); x.add(\"a\"); x.add(\"b\"); x.add(\"c\"); " + + "Iterator y = x.iterator(); String total = \"\"; while (y.hasNext()) total += y.next(); return total;")); assertEquals(3, exec("def x = new ArrayList(); x.add(2); x.add(3); x.add(-2); def y = x.iterator(); " + "def total = 0; while (y.hasNext()) total += y.next(); return total;")); } @@ -35,10 +33,8 @@ public class BasicAPITests extends ScriptTestCase { public void testSetIterator() { assertEquals(3, exec("Set x = new HashSet(); x.add(2); x.add(3); x.add(-2); Iterator y = x.iterator(); " + "int total = 0; while (y.hasNext()) total += y.next(); return total;")); - assertEquals(3, exec("Set x = new HashSet(); x.add(2); x.add(3); x.add(-2); Iterator y = x.iterator(); " + - "int total = 0; while (y.hasNext()) total += (int)y.next(); return total;")); - assertEquals("abc", exec("Set x = new HashSet(); x.add(\"a\"); x.add(\"b\"); x.add(\"c\"); " + - "Iterator y = x.iterator(); String total = \"\"; while (y.hasNext()) total += y.next(); return total;")); + assertEquals("abc", exec("Set x = new HashSet(); x.add(\"a\"); x.add(\"b\"); x.add(\"c\"); " + + "Iterator y = x.iterator(); String total = \"\"; while (y.hasNext()) total += y.next(); return total;")); assertEquals(3, exec("def x = new HashSet(); x.add(2); x.add(3); x.add(-2); def y = x.iterator(); " + "def total = 0; while (y.hasNext()) total += (int)y.next(); return total;")); } @@ -78,8 +74,6 @@ public class BasicAPITests extends ScriptTestCase { assertEquals(1, exec("def x = new ArrayList(); x.add(5); return x.length")); assertEquals(5, exec("def x = new ArrayList(); x.add(5); return x[0]")); assertEquals(1, exec("List x = new ArrayList(); x.add('Hallo'); return x.length")); - assertEquals(1, exec("List x = new ArrayList(); x.add('Hallo'); return x.length")); - assertEquals(1, exec("List x = new ArrayList(); x.add('Hallo'); return x.length")); } public void testDefAssignments() { diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicStatementTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicStatementTests.java index f0022e6bcf1..0d6a54b515b 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicStatementTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicStatementTests.java @@ -135,7 +135,7 @@ public class BasicStatementTests extends ScriptTestCase { assertEquals(2.0, exec("double a = 2; return a;")); assertEquals(false, exec("boolean a = false; return a;")); assertEquals("string", exec("String a = \"string\"; return a;")); - assertEquals(HashMap.class, exec("Map a = new HashMap(); return a;").getClass()); + assertEquals(HashMap.class, exec("Map a = new HashMap(); return a;").getClass()); assertEquals(byte[].class, exec("byte[] a = new byte[1]; return a;").getClass()); assertEquals(short[].class, exec("short[] a = new short[1]; return a;").getClass()); @@ -146,7 +146,7 @@ public class BasicStatementTests extends ScriptTestCase { assertEquals(double[].class, exec("double[] a = new double[1]; return a;").getClass()); assertEquals(boolean[].class, exec("boolean[] a = new boolean[1]; return a;").getClass()); assertEquals(String[].class, exec("String[] a = new String[1]; return a;").getClass()); - assertEquals(Map[].class, exec("Map[] a = new Map[1]; return a;").getClass()); + assertEquals(Map[].class, exec("Map[] a = new Map[1]; return a;").getClass()); assertEquals(byte[][].class, exec("byte[][] a = new byte[1][2]; return a;").getClass()); assertEquals(short[][][].class, exec("short[][][] a = new short[1][2][3]; return a;").getClass()); @@ -157,7 +157,7 @@ public class BasicStatementTests extends ScriptTestCase { assertEquals(double[][][][].class, exec("double[][][][] a = new double[1][2][3][4]; return a;").getClass()); assertEquals(boolean[][][][][].class, exec("boolean[][][][][] a = new boolean[1][2][3][4][5]; return a;").getClass()); assertEquals(String[][].class, exec("String[][] a = new String[1][2]; return a;").getClass()); - assertEquals(Map[][][].class, exec("Map[][][] a = new Map[1][2][3]; return a;").getClass()); + assertEquals(Map[][][].class, exec("Map[][][] a = new Map[1][2][3]; return a;").getClass()); } public void testContinueStatement() { @@ -174,6 +174,6 @@ public class BasicStatementTests extends ScriptTestCase { assertEquals(5, exec("int x = 5; return x;")); assertEquals(4, exec("int[] x = new int[2]; x[1] = 4; return x[1];")); assertEquals(5, ((short[])exec("short[] s = new short[3]; s[1] = 5; return s;"))[1]); - assertEquals(10, ((Map)exec("Map s = new HashMap< String , Object >(); s.put(\"x\", 10); return s;")).get("x")); + assertEquals(10, ((Map)exec("Map s = new HashMap(); s.put(\"x\", 10); return s;")).get("x")); } } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/NoSemiColonTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/NoSemiColonTests.java index f2e65fc680c..e4af7a2d166 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/NoSemiColonTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/NoSemiColonTests.java @@ -35,7 +35,7 @@ public class NoSemiColonTests extends ScriptTestCase { assertEquals(2.0, exec("double a = 2; return a")); assertEquals(false, exec("boolean a = false; return a")); assertEquals("string", exec("String a = \"string\"; return a")); - assertEquals(HashMap.class, exec("Map a = new HashMap(); return a").getClass()); + assertEquals(HashMap.class, exec("Map a = new HashMap(); return a").getClass()); assertEquals(byte[].class, exec("byte[] a = new byte[1]; return a").getClass()); assertEquals(short[].class, exec("short[] a = new short[1]; return a").getClass()); @@ -46,7 +46,7 @@ public class NoSemiColonTests extends ScriptTestCase { assertEquals(double[].class, exec("double[] a = new double[1]; return a").getClass()); assertEquals(boolean[].class, exec("boolean[] a = new boolean[1]; return a").getClass()); assertEquals(String[].class, exec("String[] a = new String[1]; return a").getClass()); - assertEquals(Map[].class, exec("Map[] a = new Map[1]; return a").getClass()); + assertEquals(Map[].class, exec("Map[] a = new Map[1]; return a").getClass()); assertEquals(byte[][].class, exec("byte[][] a = new byte[1][2]; return a").getClass()); assertEquals(short[][][].class, exec("short[][][] a = new short[1][2][3]; return a").getClass()); @@ -57,7 +57,7 @@ public class NoSemiColonTests extends ScriptTestCase { assertEquals(double[][][][].class, exec("double[][][][] a = new double[1][2][3][4]; return a").getClass()); assertEquals(boolean[][][][][].class, exec("boolean[][][][][] a = new boolean[1][2][3][4][5]; return a").getClass()); assertEquals(String[][].class, exec("String[][] a = new String[1][2]; return a").getClass()); - assertEquals(Map[][][].class, exec("Map[][][] a = new Map[1][2][3]; return a").getClass()); + assertEquals(Map[][][].class, exec("Map[][][] a = new Map[1][2][3]; return a").getClass()); } public void testExpression() { @@ -73,6 +73,6 @@ public class NoSemiColonTests extends ScriptTestCase { assertEquals(5, exec("int x = 5; return x")); assertEquals(4, exec("int[] x = new int[2]; x[1] = 4; return x[1]")); assertEquals(5, ((short[])exec("short[] s = new short[3]; s[1] = 5; return s"))[1]); - assertEquals(10, ((Map)exec("Map s = new HashMap< String,Object>(); s.put(\"x\", 10); return s")).get("x")); + assertEquals(10, ((Map)exec("Map s = new HashMap(); s.put(\"x\", 10); return s")).get("x")); } } From b9c7dbcfbd9c7862b4524d8dac35224f71a13e89 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Thu, 19 May 2016 15:25:31 -0400 Subject: [PATCH 02/22] nuke overflow detection as we cannot guarantee for def. simplify life :) --- .../painless/CompilerSettings.java | 31 -- .../elasticsearch/painless/MethodWriter.java | 286 ++--------- .../painless/PainlessScriptEngineService.java | 8 +- .../org/elasticsearch/painless/Utility.java | 341 -------------- .../painless/WriterConstants.java | 52 -- .../elasticsearch/painless/node/EBinary.java | 62 +-- .../elasticsearch/painless/node/EChain.java | 10 +- .../elasticsearch/painless/node/EUnary.java | 19 +- .../painless/FloatOverflowDisabledTests.java | 293 ------------ ...bledTests.java => FloatOverflowTests.java} | 13 +- .../IntegerOverflowDisabledTests.java | 444 ------------------ ...edTests.java => IntegerOverflowTests.java} | 13 +- .../painless/ScriptTestCase.java | 2 +- .../elasticsearch/painless/UtilityTests.java | 250 ---------- 14 files changed, 66 insertions(+), 1758 deletions(-) delete mode 100644 modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowDisabledTests.java rename modules/lang-painless/src/test/java/org/elasticsearch/painless/{FloatOverflowEnabledTests.java => FloatOverflowTests.java} (94%) delete mode 100644 modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowDisabledTests.java rename modules/lang-painless/src/test/java/org/elasticsearch/painless/{IntegerOverflowEnabledTests.java => IntegerOverflowTests.java} (95%) delete mode 100644 modules/lang-painless/src/test/java/org/elasticsearch/painless/UtilityTests.java diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/CompilerSettings.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/CompilerSettings.java index 9ec26bf345a..4cafe32bb56 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/CompilerSettings.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/CompilerSettings.java @@ -24,47 +24,16 @@ package org.elasticsearch.painless; */ public final class CompilerSettings { - /** - * Constant to be used when specifying numeric overflow when compiling a script. - */ - public static final String NUMERIC_OVERFLOW = "numeric_overflow"; - /** * Constant to be used when specifying the maximum loop counter when compiling a script. */ public static final String MAX_LOOP_COUNTER = "max_loop_counter"; - /** - * Whether or not to allow numeric values to overflow without exception. - */ - private boolean numericOverflow = true; - /** * The maximum number of statements allowed to be run in a loop. */ private int maxLoopCounter = 10000; - /** - * Returns {@code true} if numeric operations should overflow, {@code false} - * if they should signal an exception. - *

- * If this value is {@code true} (default), then things behave like java: - * overflow for integer types can result in unexpected values / unexpected - * signs, and overflow for floating point types can result in infinite or - * {@code NaN} values. - */ - public final boolean getNumericOverflow() { - return numericOverflow; - } - - /** - * Set {@code true} for numerics to overflow, false to deliver exceptions. - * @see #getNumericOverflow - */ - public final void setNumericOverflow(boolean allow) { - this.numericOverflow = allow; - } - /** * Returns the value for the cumulative total number of statements that can be made in all loops * in a script before an exception is thrown. This attempts to prevent infinite loops. Note if diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java index bb362558796..cda8c23e3bf 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java @@ -34,10 +34,6 @@ import java.util.ArrayList; import java.util.Deque; import java.util.List; -import static org.elasticsearch.painless.WriterConstants.ADDEXACT_INT; -import static org.elasticsearch.painless.WriterConstants.ADDEXACT_LONG; -import static org.elasticsearch.painless.WriterConstants.ADDWOOVERLOW_DOUBLE; -import static org.elasticsearch.painless.WriterConstants.ADDWOOVERLOW_FLOAT; import static org.elasticsearch.painless.WriterConstants.DEF_ADD_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_AND_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_DIV_CALL; @@ -49,19 +45,9 @@ import static org.elasticsearch.painless.WriterConstants.DEF_RSH_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_SUB_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_USH_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_XOR_CALL; -import static org.elasticsearch.painless.WriterConstants.DIVWOOVERLOW_DOUBLE; -import static org.elasticsearch.painless.WriterConstants.DIVWOOVERLOW_FLOAT; -import static org.elasticsearch.painless.WriterConstants.DIVWOOVERLOW_INT; -import static org.elasticsearch.painless.WriterConstants.DIVWOOVERLOW_LONG; import static org.elasticsearch.painless.WriterConstants.INDY_STRING_CONCAT_BOOTSTRAP_HANDLE; import static org.elasticsearch.painless.WriterConstants.MAX_INDY_STRING_CONCAT_ARGS; -import static org.elasticsearch.painless.WriterConstants.MULEXACT_INT; -import static org.elasticsearch.painless.WriterConstants.MULEXACT_LONG; -import static org.elasticsearch.painless.WriterConstants.MULWOOVERLOW_DOUBLE; -import static org.elasticsearch.painless.WriterConstants.MULWOOVERLOW_FLOAT; import static org.elasticsearch.painless.WriterConstants.PAINLESS_ERROR_TYPE; -import static org.elasticsearch.painless.WriterConstants.REMWOOVERLOW_DOUBLE; -import static org.elasticsearch.painless.WriterConstants.REMWOOVERLOW_FLOAT; import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_APPEND_BOOLEAN; import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_APPEND_CHAR; import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_APPEND_DOUBLE; @@ -74,28 +60,6 @@ import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_CONSTRUCT import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_TOSTRING; import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_TYPE; import static org.elasticsearch.painless.WriterConstants.STRING_TYPE; -import static org.elasticsearch.painless.WriterConstants.SUBEXACT_INT; -import static org.elasticsearch.painless.WriterConstants.SUBEXACT_LONG; -import static org.elasticsearch.painless.WriterConstants.SUBWOOVERLOW_DOUBLE; -import static org.elasticsearch.painless.WriterConstants.SUBWOOVERLOW_FLOAT; -import static org.elasticsearch.painless.WriterConstants.TOBYTEEXACT_INT; -import static org.elasticsearch.painless.WriterConstants.TOBYTEEXACT_LONG; -import static org.elasticsearch.painless.WriterConstants.TOBYTEWOOVERFLOW_DOUBLE; -import static org.elasticsearch.painless.WriterConstants.TOBYTEWOOVERFLOW_FLOAT; -import static org.elasticsearch.painless.WriterConstants.TOCHAREXACT_INT; -import static org.elasticsearch.painless.WriterConstants.TOCHAREXACT_LONG; -import static org.elasticsearch.painless.WriterConstants.TOCHARWOOVERFLOW_DOUBLE; -import static org.elasticsearch.painless.WriterConstants.TOCHARWOOVERFLOW_FLOAT; -import static org.elasticsearch.painless.WriterConstants.TOFLOATWOOVERFLOW_DOUBLE; -import static org.elasticsearch.painless.WriterConstants.TOINTEXACT_LONG; -import static org.elasticsearch.painless.WriterConstants.TOINTWOOVERFLOW_DOUBLE; -import static org.elasticsearch.painless.WriterConstants.TOINTWOOVERFLOW_FLOAT; -import static org.elasticsearch.painless.WriterConstants.TOLONGWOOVERFLOW_DOUBLE; -import static org.elasticsearch.painless.WriterConstants.TOLONGWOOVERFLOW_FLOAT; -import static org.elasticsearch.painless.WriterConstants.TOSHORTEXACT_INT; -import static org.elasticsearch.painless.WriterConstants.TOSHORTEXACT_LONG; -import static org.elasticsearch.painless.WriterConstants.TOSHORTWOOVERFLOW_DOUBLE; -import static org.elasticsearch.painless.WriterConstants.TOSHORTWOOVERFLOW_FLOAT; /** * Extension of {@link GeneratorAdapter} with some utility methods. @@ -236,231 +200,53 @@ public final class MethodWriter extends GeneratorAdapter { } } - public void writeBinaryInstruction(final CompilerSettings settings, final Definition definition, + public void writeBinaryInstruction(final Definition definition, final String location, final Type type, final Operation operation) { final Sort sort = type.sort; - boolean exact = !settings.getNumericOverflow() && - ((sort == Sort.INT || sort == Sort.LONG) && - (operation == Operation.MUL || operation == Operation.DIV || - operation == Operation.ADD || operation == Operation.SUB) || - (sort == Sort.FLOAT || sort == Sort.DOUBLE) && - (operation == Operation.MUL || operation == Operation.DIV || operation == Operation.REM || - operation == Operation.ADD || operation == Operation.SUB)); - - if (exact) { - switch (sort) { - case INT: - switch (operation) { - case MUL: invokeStatic(definition.getType("Math").type, MULEXACT_INT); break; - case DIV: invokeStatic(definition.getType("Utility").type, DIVWOOVERLOW_INT); break; - case ADD: invokeStatic(definition.getType("Math").type, ADDEXACT_INT); break; - case SUB: invokeStatic(definition.getType("Math").type, SUBEXACT_INT); break; - } - - break; - case LONG: - switch (operation) { - case MUL: invokeStatic(definition.getType("Math").type, MULEXACT_LONG); break; - case DIV: invokeStatic(definition.getType("Utility").type, DIVWOOVERLOW_LONG); break; - case ADD: invokeStatic(definition.getType("Math").type, ADDEXACT_LONG); break; - case SUB: invokeStatic(definition.getType("Math").type, SUBEXACT_LONG); break; - } - - break; - case FLOAT: - switch (operation) { - case MUL: invokeStatic(definition.getType("Utility").type, MULWOOVERLOW_FLOAT); break; - case DIV: invokeStatic(definition.getType("Utility").type, DIVWOOVERLOW_FLOAT); break; - case REM: invokeStatic(definition.getType("Utility").type, REMWOOVERLOW_FLOAT); break; - case ADD: invokeStatic(definition.getType("Utility").type, ADDWOOVERLOW_FLOAT); break; - case SUB: invokeStatic(definition.getType("Utility").type, SUBWOOVERLOW_FLOAT); break; - default: - throw new IllegalStateException("Error " + location + ": Illegal tree structure."); - } - - break; - case DOUBLE: - switch (operation) { - case MUL: invokeStatic(definition.getType("Utility").type, MULWOOVERLOW_DOUBLE); break; - case DIV: invokeStatic(definition.getType("Utility").type, DIVWOOVERLOW_DOUBLE); break; - case REM: invokeStatic(definition.getType("Utility").type, REMWOOVERLOW_DOUBLE); break; - case ADD: invokeStatic(definition.getType("Utility").type, ADDWOOVERLOW_DOUBLE); break; - case SUB: invokeStatic(definition.getType("Utility").type, SUBWOOVERLOW_DOUBLE); break; - default: - throw new IllegalStateException("Error " + location + ": Illegal tree structure."); - } - - break; + + if ((sort == Sort.FLOAT || sort == Sort.DOUBLE) && + (operation == Operation.LSH || operation == Operation.USH || + operation == Operation.RSH || operation == Operation.BWAND || + operation == Operation.XOR || operation == Operation.BWOR)) { + throw new IllegalStateException("Error " + location + ": Illegal tree structure."); + } + + if (sort == Sort.DEF) { + switch (operation) { + case MUL: invokeStatic(definition.getType("Def").type, DEF_MUL_CALL); break; + case DIV: invokeStatic(definition.getType("Def").type, DEF_DIV_CALL); break; + case REM: invokeStatic(definition.getType("Def").type, DEF_REM_CALL); break; + case ADD: invokeStatic(definition.getType("Def").type, DEF_ADD_CALL); break; + case SUB: invokeStatic(definition.getType("Def").type, DEF_SUB_CALL); break; + case LSH: invokeStatic(definition.getType("Def").type, DEF_LSH_CALL); break; + case USH: invokeStatic(definition.getType("Def").type, DEF_RSH_CALL); break; + case RSH: invokeStatic(definition.getType("Def").type, DEF_USH_CALL); break; + case BWAND: invokeStatic(definition.getType("Def").type, DEF_AND_CALL); break; + case XOR: invokeStatic(definition.getType("Def").type, DEF_XOR_CALL); break; + case BWOR: invokeStatic(definition.getType("Def").type, DEF_OR_CALL); break; default: throw new IllegalStateException("Error " + location + ": Illegal tree structure."); } } else { - if ((sort == Sort.FLOAT || sort == Sort.DOUBLE) && - (operation == Operation.LSH || operation == Operation.USH || - operation == Operation.RSH || operation == Operation.BWAND || - operation == Operation.XOR || operation == Operation.BWOR)) { - throw new IllegalStateException("Error " + location + ": Illegal tree structure."); - } - - if (sort == Sort.DEF) { - switch (operation) { - case MUL: invokeStatic(definition.getType("Def").type, DEF_MUL_CALL); break; - case DIV: invokeStatic(definition.getType("Def").type, DEF_DIV_CALL); break; - case REM: invokeStatic(definition.getType("Def").type, DEF_REM_CALL); break; - case ADD: invokeStatic(definition.getType("Def").type, DEF_ADD_CALL); break; - case SUB: invokeStatic(definition.getType("Def").type, DEF_SUB_CALL); break; - case LSH: invokeStatic(definition.getType("Def").type, DEF_LSH_CALL); break; - case USH: invokeStatic(definition.getType("Def").type, DEF_RSH_CALL); break; - case RSH: invokeStatic(definition.getType("Def").type, DEF_USH_CALL); break; - case BWAND: invokeStatic(definition.getType("Def").type, DEF_AND_CALL); break; - case XOR: invokeStatic(definition.getType("Def").type, DEF_XOR_CALL); break; - case BWOR: invokeStatic(definition.getType("Def").type, DEF_OR_CALL); break; - default: - throw new IllegalStateException("Error " + location + ": Illegal tree structure."); - } - } else { - switch (operation) { - case MUL: math(GeneratorAdapter.MUL, type.type); break; - case DIV: math(GeneratorAdapter.DIV, type.type); break; - case REM: math(GeneratorAdapter.REM, type.type); break; - case ADD: math(GeneratorAdapter.ADD, type.type); break; - case SUB: math(GeneratorAdapter.SUB, type.type); break; - case LSH: math(GeneratorAdapter.SHL, type.type); break; - case USH: math(GeneratorAdapter.USHR, type.type); break; - case RSH: math(GeneratorAdapter.SHR, type.type); break; - case BWAND: math(GeneratorAdapter.AND, type.type); break; - case XOR: math(GeneratorAdapter.XOR, type.type); break; - case BWOR: math(GeneratorAdapter.OR, type.type); break; - default: - throw new IllegalStateException("Error " + location + ": Illegal tree structure."); - } + switch (operation) { + case MUL: math(GeneratorAdapter.MUL, type.type); break; + case DIV: math(GeneratorAdapter.DIV, type.type); break; + case REM: math(GeneratorAdapter.REM, type.type); break; + case ADD: math(GeneratorAdapter.ADD, type.type); break; + case SUB: math(GeneratorAdapter.SUB, type.type); break; + case LSH: math(GeneratorAdapter.SHL, type.type); break; + case USH: math(GeneratorAdapter.USHR, type.type); break; + case RSH: math(GeneratorAdapter.SHR, type.type); break; + case BWAND: math(GeneratorAdapter.AND, type.type); break; + case XOR: math(GeneratorAdapter.XOR, type.type); break; + case BWOR: math(GeneratorAdapter.OR, type.type); break; + default: + throw new IllegalStateException("Error " + location + ": Illegal tree structure."); } } } - /** - * Called for any compound assignment (including increment/decrement instructions). - * We have to be stricter than writeBinary and do overflow checks against the original type's size - * instead of the promoted type's size, since the result will be implicitly cast back. - * - * @return This will be true if an instruction is written, false otherwise. - */ - public boolean writeExactInstruction( - final Definition definition, final Sort fsort, final Sort tsort) { - if (fsort == Sort.DOUBLE) { - if (tsort == Sort.FLOAT) { - invokeStatic(definition.getType("Utility").type, TOFLOATWOOVERFLOW_DOUBLE); - } else if (tsort == Sort.FLOAT_OBJ) { - invokeStatic(definition.getType("Utility").type, TOFLOATWOOVERFLOW_DOUBLE); - checkCast(definition.getType("Float").type); - } else if (tsort == Sort.LONG) { - invokeStatic(definition.getType("Utility").type, TOLONGWOOVERFLOW_DOUBLE); - } else if (tsort == Sort.LONG_OBJ) { - invokeStatic(definition.getType("Utility").type, TOLONGWOOVERFLOW_DOUBLE); - checkCast(definition.getType("Long").type); - } else if (tsort == Sort.INT) { - invokeStatic(definition.getType("Utility").type, TOINTWOOVERFLOW_DOUBLE); - } else if (tsort == Sort.INT_OBJ) { - invokeStatic(definition.getType("Utility").type, TOINTWOOVERFLOW_DOUBLE); - checkCast(definition.getType("Integer").type); - } else if (tsort == Sort.CHAR) { - invokeStatic(definition.getType("Utility").type, TOCHARWOOVERFLOW_DOUBLE); - } else if (tsort == Sort.CHAR_OBJ) { - invokeStatic(definition.getType("Utility").type, TOCHARWOOVERFLOW_DOUBLE); - checkCast(definition.getType("Character").type); - } else if (tsort == Sort.SHORT) { - invokeStatic(definition.getType("Utility").type, TOSHORTWOOVERFLOW_DOUBLE); - } else if (tsort == Sort.SHORT_OBJ) { - invokeStatic(definition.getType("Utility").type, TOSHORTWOOVERFLOW_DOUBLE); - checkCast(definition.getType("Short").type); - } else if (tsort == Sort.BYTE) { - invokeStatic(definition.getType("Utility").type, TOBYTEWOOVERFLOW_DOUBLE); - } else if (tsort == Sort.BYTE_OBJ) { - invokeStatic(definition.getType("Utility").type, TOBYTEWOOVERFLOW_DOUBLE); - checkCast(definition.getType("Byte").type); - } else { - return false; - } - } else if (fsort == Sort.FLOAT) { - if (tsort == Sort.LONG) { - invokeStatic(definition.getType("Utility").type, TOLONGWOOVERFLOW_FLOAT); - } else if (tsort == Sort.LONG_OBJ) { - invokeStatic(definition.getType("Utility").type, TOLONGWOOVERFLOW_FLOAT); - checkCast(definition.getType("Long").type); - } else if (tsort == Sort.INT) { - invokeStatic(definition.getType("Utility").type, TOINTWOOVERFLOW_FLOAT); - } else if (tsort == Sort.INT_OBJ) { - invokeStatic(definition.getType("Utility").type, TOINTWOOVERFLOW_FLOAT); - checkCast(definition.getType("Integer").type); - } else if (tsort == Sort.CHAR) { - invokeStatic(definition.getType("Utility").type, TOCHARWOOVERFLOW_FLOAT); - } else if (tsort == Sort.CHAR_OBJ) { - invokeStatic(definition.getType("Utility").type, TOCHARWOOVERFLOW_FLOAT); - checkCast(definition.getType("Character").type); - } else if (tsort == Sort.SHORT) { - invokeStatic(definition.getType("Utility").type, TOSHORTWOOVERFLOW_FLOAT); - } else if (tsort == Sort.SHORT_OBJ) { - invokeStatic(definition.getType("Utility").type, TOSHORTWOOVERFLOW_FLOAT); - checkCast(definition.getType("Short").type); - } else if (tsort == Sort.BYTE) { - invokeStatic(definition.getType("Utility").type, TOBYTEWOOVERFLOW_FLOAT); - } else if (tsort == Sort.BYTE_OBJ) { - invokeStatic(definition.getType("Utility").type, TOBYTEWOOVERFLOW_FLOAT); - checkCast(definition.getType("Byte").type); - } else { - return false; - } - } else if (fsort == Sort.LONG) { - if (tsort == Sort.INT) { - invokeStatic(definition.getType("Math").type, TOINTEXACT_LONG); - } else if (tsort == Sort.INT_OBJ) { - invokeStatic(definition.getType("Math").type, TOINTEXACT_LONG); - checkCast(definition.getType("Integer").type); - } else if (tsort == Sort.CHAR) { - invokeStatic(definition.getType("Utility").type, TOCHAREXACT_LONG); - } else if (tsort == Sort.CHAR_OBJ) { - invokeStatic(definition.getType("Utility").type, TOCHAREXACT_LONG); - checkCast(definition.getType("Character").type); - } else if (tsort == Sort.SHORT) { - invokeStatic(definition.getType("Utility").type, TOSHORTEXACT_LONG); - } else if (tsort == Sort.SHORT_OBJ) { - invokeStatic(definition.getType("Utility").type, TOSHORTEXACT_LONG); - checkCast(definition.getType("Short").type); - } else if (tsort == Sort.BYTE) { - invokeStatic(definition.getType("Utility").type, TOBYTEEXACT_LONG); - } else if (tsort == Sort.BYTE_OBJ) { - invokeStatic(definition.getType("Utility").type, TOBYTEEXACT_LONG); - checkCast(definition.getType("Byte").type); - } else { - return false; - } - } else if (fsort == Sort.INT) { - if (tsort == Sort.CHAR) { - invokeStatic(definition.getType("Utility").type, TOCHAREXACT_INT); - } else if (tsort == Sort.CHAR_OBJ) { - invokeStatic(definition.getType("Utility").type, TOCHAREXACT_INT); - checkCast(definition.getType("Character").type); - } else if (tsort == Sort.SHORT) { - invokeStatic(definition.getType("Utility").type, TOSHORTEXACT_INT); - } else if (tsort == Sort.SHORT_OBJ) { - invokeStatic(definition.getType("Utility").type, TOSHORTEXACT_INT); - checkCast(definition.getType("Short").type); - } else if (tsort == Sort.BYTE) { - invokeStatic(definition.getType("Utility").type, TOBYTEEXACT_INT); - } else if (tsort == Sort.BYTE_OBJ) { - invokeStatic(definition.getType("Utility").type, TOBYTEEXACT_INT); - checkCast(definition.getType("Byte").type); - } else { - return false; - } - } else { - return false; - } - - return true; - } - public void writeDup(final int size, final int xsize) { if (size == 1) { if (xsize == 2) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java index 1d11dae720f..4c627d08eca 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java @@ -115,13 +115,7 @@ public final class PainlessScriptEngineService extends AbstractComponent impleme // Use custom settings specified by params. compilerSettings = new CompilerSettings(); Map copy = new HashMap<>(params); - String value = copy.remove(CompilerSettings.NUMERIC_OVERFLOW); - - if (value != null) { - compilerSettings.setNumericOverflow(Boolean.parseBoolean(value)); - } - - value = copy.remove(CompilerSettings.MAX_LOOP_COUNTER); + String value = copy.remove(CompilerSettings.MAX_LOOP_COUNTER); if (value != null) { compilerSettings.setMaxLoopCounter(Integer.parseInt(value)); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java index 32641649827..559e909ed77 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java @@ -481,347 +481,6 @@ public class Utility { return value.charAt(0); } - // although divide by zero is guaranteed, the special overflow case is not caught. - // its not needed for remainder because it is not possible there. - // see https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.17.2 - - /** - * Integer divide without overflow - * @throws ArithmeticException on overflow or divide-by-zero - */ - public static int divideWithoutOverflow(int x, int y) { - if (x == Integer.MIN_VALUE && y == -1) { - throw new ArithmeticException("integer overflow"); - } - return x / y; - } - - /** - * Long divide without overflow - * @throws ArithmeticException on overflow or divide-by-zero - */ - public static long divideWithoutOverflow(long x, long y) { - if (x == Long.MIN_VALUE && y == -1L) { - throw new ArithmeticException("long overflow"); - } - return x / y; - } - - // byte, short, and char are promoted to int for normal operations, - // so the JDK exact methods are typically used, and the result has a wider range. - // but compound assignments and increment/decrement operators (e.g. byte b = Byte.MAX_VALUE; b++;) - // implicitly cast back to the original type: so these need to be checked against the original range. - - /** - * Like {@link Math#toIntExact(long)} but for byte range. - */ - public static byte toByteExact(int value) { - byte s = (byte) value; - if (s != value) { - throw new ArithmeticException("byte overflow"); - } - return s; - } - - /** - * Like {@link Math#toIntExact(long)} but for byte range. - */ - public static byte toByteExact(long value) { - byte s = (byte) value; - if (s != value) { - throw new ArithmeticException("byte overflow"); - } - return s; - } - - /** - * Like {@link Math#toIntExact(long)} but for byte range. - */ - public static byte toByteWithoutOverflow(float value) { - if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) { - throw new ArithmeticException("byte overflow"); - } - return (byte)value; - } - - /** - * Like {@link Math#toIntExact(long)} but for byte range. - */ - public static byte toByteWithoutOverflow(double value) { - if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) { - throw new ArithmeticException("byte overflow"); - } - return (byte)value; - } - - /** - * Like {@link Math#toIntExact(long)} but for short range. - */ - public static short toShortExact(int value) { - short s = (short) value; - if (s != value) { - throw new ArithmeticException("short overflow"); - } - return s; - } - - /** - * Like {@link Math#toIntExact(long)} but for short range. - */ - public static short toShortExact(long value) { - short s = (short) value; - if (s != value) { - throw new ArithmeticException("short overflow"); - } - return s; - } - - /** - * Like {@link Math#toIntExact(long)} but for short range. - */ - public static short toShortWithoutOverflow(float value) { - if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) { - throw new ArithmeticException("short overflow"); - } - return (short)value; - } - - /** - * Like {@link Math#toIntExact(long)} but for short range. - */ - public static short toShortExact(double value) { - if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) { - throw new ArithmeticException("short overflow"); - } - return (short)value; - } - - /** - * Like {@link Math#toIntExact(long)} but for char range. - */ - public static char toCharExact(int value) { - char s = (char) value; - if (s != value) { - throw new ArithmeticException("char overflow"); - } - return s; - } - - /** - * Like {@link Math#toIntExact(long)} but for char range. - */ - public static char toCharExact(long value) { - char s = (char) value; - if (s != value) { - throw new ArithmeticException("char overflow"); - } - return s; - } - - /** - * Like {@link Math#toIntExact(long)} but for char range. - */ - public static char toCharWithoutOverflow(float value) { - if (value < Character.MIN_VALUE || value > Character.MAX_VALUE) { - throw new ArithmeticException("char overflow"); - } - return (char)value; - } - - /** - * Like {@link Math#toIntExact(long)} but for char range. - */ - public static char toCharWithoutOverflow(double value) { - if (value < Character.MIN_VALUE || value > Character.MAX_VALUE) { - throw new ArithmeticException("char overflow"); - } - return (char)value; - } - - /** - * Like {@link Math#toIntExact(long)} but for int range. - */ - public static int toIntWithoutOverflow(float value) { - if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { - throw new ArithmeticException("int overflow"); - } - return (int)value; - } - - /** - * Like {@link Math#toIntExact(long)} but for int range. - */ - public static int toIntWithoutOverflow(double value) { - if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { - throw new ArithmeticException("int overflow"); - } - return (int)value; - } - - /** - * Like {@link Math#toIntExact(long)} but for long range. - */ - public static long toLongWithoutOverflow(float value) { - if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) { - throw new ArithmeticException("long overflow"); - } - return (long)value; - } - - /** - * Like {@link Math#toIntExact(long)} but for long range. - */ - public static float toLongWithoutOverflow(double value) { - if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) { - throw new ArithmeticException("long overflow"); - } - return (long)value; - } - - /** - * Like {@link Math#toIntExact(long)} but for float range. - */ - public static float toFloatWithoutOverflow(double value) { - if (value < Float.MIN_VALUE || value > Float.MAX_VALUE) { - throw new ArithmeticException("float overflow"); - } - return (float)value; - } - - /** - * Checks for overflow, result is infinite but operands are finite - * @throws ArithmeticException if overflow occurred - */ - private static float checkInfFloat(float x, float y, float z) { - if (Float.isInfinite(z)) { - if (Float.isFinite(x) && Float.isFinite(y)) { - throw new ArithmeticException("float overflow"); - } - } - return z; - } - - /** - * Checks for NaN, result is NaN but operands are finite - * @throws ArithmeticException if overflow occurred - */ - private static float checkNaNFloat(float x, float y, float z) { - if (Float.isNaN(z)) { - if (Float.isFinite(x) && Float.isFinite(y)) { - throw new ArithmeticException("NaN"); - } - } - return z; - } - - /** - * Checks for NaN, result is infinite but operands are finite - * @throws ArithmeticException if overflow occurred - */ - private static double checkInfDouble(double x, double y, double z) { - if (Double.isInfinite(z)) { - if (Double.isFinite(x) && Double.isFinite(y)) { - throw new ArithmeticException("double overflow"); - } - } - return z; - } - - /** - * Checks for NaN, result is NaN but operands are finite - * @throws ArithmeticException if overflow occurred - */ - private static double checkNaNDouble(double x, double y, double z) { - if (Double.isNaN(z)) { - if (Double.isFinite(x) && Double.isFinite(y)) { - throw new ArithmeticException("NaN"); - } - } - return z; - } - - /** - * Adds two floats but throws {@code ArithmeticException} - * if the result overflows. - */ - public static float addWithoutOverflow(float x, float y) { - return checkInfFloat(x, y, x + y); - } - - /** - * Adds two doubles but throws {@code ArithmeticException} - * if the result overflows. - */ - public static double addWithoutOverflow(double x, double y) { - return checkInfDouble(x, y, x + y); - } - - /** - * Subtracts two floats but throws {@code ArithmeticException} - * if the result overflows. - */ - public static float subtractWithoutOverflow(float x, float y) { - return checkInfFloat(x, y, x - y); - } - - /** - * Subtracts two doubles but throws {@code ArithmeticException} - * if the result overflows. - */ - public static double subtractWithoutOverflow(double x, double y) { - return checkInfDouble(x, y , x - y); - } - - /** - * Multiplies two floats but throws {@code ArithmeticException} - * if the result overflows. - */ - public static float multiplyWithoutOverflow(float x, float y) { - return checkInfFloat(x, y, x * y); - } - - /** - * Multiplies two doubles but throws {@code ArithmeticException} - * if the result overflows. - */ - public static double multiplyWithoutOverflow(double x, double y) { - return checkInfDouble(x, y, x * y); - } - - /** - * Divides two floats but throws {@code ArithmeticException} - * if the result overflows, or would create NaN from finite - * inputs ({@code x == 0, y == 0}) - */ - public static float divideWithoutOverflow(float x, float y) { - return checkNaNFloat(x, y, checkInfFloat(x, y, x / y)); - } - - /** - * Divides two doubles but throws {@code ArithmeticException} - * if the result overflows, or would create NaN from finite - * inputs ({@code x == 0, y == 0}) - */ - public static double divideWithoutOverflow(double x, double y) { - return checkNaNDouble(x, y, checkInfDouble(x, y, x / y)); - } - - /** - * Takes remainder two floats but throws {@code ArithmeticException} - * if the result would create NaN from finite inputs ({@code y == 0}) - */ - public static float remainderWithoutOverflow(float x, float y) { - return checkNaNFloat(x, y, x % y); - } - - /** - * Divides two doubles but throws {@code ArithmeticException} - * if the result would create NaN from finite inputs ({@code y == 0}) - */ - public static double remainderWithoutOverflow(double x, double y) { - return checkNaNDouble(x, y, x % y); - } - public static boolean checkEquals(final Object left, final Object right) { if (left != null) { return left.equals(right); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java index 6bdb9856114..d167646e9dd 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java @@ -27,7 +27,6 @@ import org.objectweb.asm.Type; import org.objectweb.asm.commons.Method; import java.lang.invoke.CallSite; -import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.util.Map; @@ -116,59 +115,8 @@ public final class WriterConstants { public final static Method STRINGBUILDER_APPEND_OBJECT = getAsmMethod(StringBuilder.class, "append", Object.class); public final static Method STRINGBUILDER_TOSTRING = getAsmMethod(String.class, "toString"); - public final static Method TOINTEXACT_LONG = getAsmMethod(int.class, "toIntExact", long.class); - public final static Method NEGATEEXACT_INT = getAsmMethod(int.class, "negateExact", int.class); - public final static Method NEGATEEXACT_LONG = getAsmMethod(long.class, "negateExact", long.class); - public final static Method MULEXACT_INT = getAsmMethod(int.class, "multiplyExact", int.class, int.class); - public final static Method MULEXACT_LONG = getAsmMethod(long.class, "multiplyExact", long.class, long.class); - public final static Method ADDEXACT_INT = getAsmMethod(int.class, "addExact", int.class, int.class); - public final static Method ADDEXACT_LONG = getAsmMethod(long.class, "addExact", long.class, long.class); - public final static Method SUBEXACT_INT = getAsmMethod(int.class, "subtractExact", int.class, int.class); - public final static Method SUBEXACT_LONG = getAsmMethod(long.class, "subtractExact", long.class, long.class); - public final static Method CHECKEQUALS = getAsmMethod(boolean.class, "checkEquals", Object.class, Object.class); - public final static Method TOBYTEEXACT_INT = getAsmMethod(byte.class, "toByteExact", int.class); - public final static Method TOBYTEEXACT_LONG = getAsmMethod(byte.class, "toByteExact", long.class); - public final static Method TOBYTEWOOVERFLOW_FLOAT = getAsmMethod(byte.class, "toByteWithoutOverflow", float.class); - public final static Method TOBYTEWOOVERFLOW_DOUBLE = getAsmMethod(byte.class, "toByteWithoutOverflow", double.class); - public final static Method TOSHORTEXACT_INT = getAsmMethod(short.class, "toShortExact", int.class); - public final static Method TOSHORTEXACT_LONG = getAsmMethod(short.class, "toShortExact", long.class); - public final static Method TOSHORTWOOVERFLOW_FLOAT = getAsmMethod(short.class, "toShortWithoutOverflow", float.class); - public final static Method TOSHORTWOOVERFLOW_DOUBLE = getAsmMethod(short.class, "toShortWihtoutOverflow", double.class); - public final static Method TOCHAREXACT_INT = getAsmMethod(char.class, "toCharExact", int.class); - public final static Method TOCHAREXACT_LONG = getAsmMethod(char.class, "toCharExact", long.class); - public final static Method TOCHARWOOVERFLOW_FLOAT = getAsmMethod(char.class, "toCharWithoutOverflow", float.class); - public final static Method TOCHARWOOVERFLOW_DOUBLE = getAsmMethod(char.class, "toCharWithoutOverflow", double.class); - public final static Method TOINTWOOVERFLOW_FLOAT = getAsmMethod(int.class, "toIntWithoutOverflow", float.class); - public final static Method TOINTWOOVERFLOW_DOUBLE = getAsmMethod(int.class, "toIntWithoutOverflow", double.class); - public final static Method TOLONGWOOVERFLOW_FLOAT = getAsmMethod(long.class, "toLongWithoutOverflow", float.class); - public final static Method TOLONGWOOVERFLOW_DOUBLE = getAsmMethod(long.class, "toLongWithoutOverflow", double.class); - public final static Method TOFLOATWOOVERFLOW_DOUBLE = getAsmMethod(float.class , "toFloatWihtoutOverflow", double.class); - public final static Method MULWOOVERLOW_FLOAT = - getAsmMethod(float.class, "multiplyWithoutOverflow", float.class, float.class); - public final static Method MULWOOVERLOW_DOUBLE = - getAsmMethod(double.class, "multiplyWithoutOverflow", double.class, double.class); - public final static Method DIVWOOVERLOW_INT = - getAsmMethod(int.class, "divideWithoutOverflow", int.class, int.class); - public final static Method DIVWOOVERLOW_LONG = - getAsmMethod(long.class, "divideWithoutOverflow", long.class, long.class); - public final static Method DIVWOOVERLOW_FLOAT = - getAsmMethod(float.class, "divideWithoutOverflow", float.class, float.class); - public final static Method DIVWOOVERLOW_DOUBLE = - getAsmMethod(double.class, "divideWithoutOverflow", double.class, double.class); - public final static Method REMWOOVERLOW_FLOAT = - getAsmMethod(float.class, "remainderWithoutOverflow", float.class, float.class); - public final static Method REMWOOVERLOW_DOUBLE = - getAsmMethod(double.class, "remainderWithoutOverflow", double.class, double.class); - public final static Method ADDWOOVERLOW_FLOAT = - getAsmMethod(float.class, "addWithoutOverflow", float.class, float.class); - public final static Method ADDWOOVERLOW_DOUBLE = - getAsmMethod(double.class, "addWithoutOverflow", double.class, double.class); - public final static Method SUBWOOVERLOW_FLOAT = - getAsmMethod(float.class, "subtractWithoutOverflow", float.class, float.class); - public final static Method SUBWOOVERLOW_DOUBLE = - getAsmMethod(double.class, "subtractWithoutOverflow", double.class, double.class); private static Method getAsmMethod(final Class rtype, final String name, final Class... ptypes) { return new Method(name, MethodType.methodType(rtype, ptypes).toMethodDescriptorString()); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java index 18b9de80fb6..f22b7394ca0 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java @@ -94,21 +94,16 @@ public final class EBinary extends AExpression { right = right.cast(settings, definition, variables); if (left.constant != null && right.constant != null) { - final boolean overflow = settings.getNumericOverflow(); final Sort sort = promote.sort; if (sort == Sort.INT) { - constant = overflow ? (int)left.constant * (int)right.constant : - Math.multiplyExact((int)left.constant, (int)right.constant); + constant = (int)left.constant * (int)right.constant; } else if (sort == Sort.LONG) { - constant = overflow ? (long)left.constant * (long)right.constant : - Math.multiplyExact((long)left.constant, (long)right.constant); + constant = (long)left.constant * (long)right.constant; } else if (sort == Sort.FLOAT) { - constant = overflow ? (float)left.constant * (float)right.constant : - org.elasticsearch.painless.Utility.multiplyWithoutOverflow((float)left.constant, (float)right.constant); + constant = (float)left.constant * (float)right.constant; } else if (sort == Sort.DOUBLE) { - constant = overflow ? (double)left.constant * (double)right.constant : - org.elasticsearch.painless.Utility.multiplyWithoutOverflow((double)left.constant, (double)right.constant); + constant = (double)left.constant * (double)right.constant; } else { throw new IllegalStateException(error("Illegal tree structure.")); } @@ -135,21 +130,16 @@ public final class EBinary extends AExpression { right = right.cast(settings, definition, variables); if (left.constant != null && right.constant != null) { - final boolean overflow = settings.getNumericOverflow(); final Sort sort = promote.sort; if (sort == Sort.INT) { - constant = overflow ? (int)left.constant / (int)right.constant : - org.elasticsearch.painless.Utility.divideWithoutOverflow((int)left.constant, (int)right.constant); + constant = (int)left.constant / (int)right.constant; } else if (sort == Sort.LONG) { - constant = overflow ? (long)left.constant / (long)right.constant : - org.elasticsearch.painless.Utility.divideWithoutOverflow((long)left.constant, (long)right.constant); + constant = (long)left.constant / (long)right.constant; } else if (sort == Sort.FLOAT) { - constant = overflow ? (float)left.constant / (float)right.constant : - org.elasticsearch.painless.Utility.divideWithoutOverflow((float)left.constant, (float)right.constant); + constant = (float)left.constant / (float)right.constant; } else if (sort == Sort.DOUBLE) { - constant = overflow ? (double)left.constant / (double)right.constant : - org.elasticsearch.painless.Utility.divideWithoutOverflow((double)left.constant, (double)right.constant); + constant = (double)left.constant / (double)right.constant; } else { throw new IllegalStateException(error("Illegal tree structure.")); } @@ -176,7 +166,6 @@ public final class EBinary extends AExpression { right = right.cast(settings, definition, variables); if (left.constant != null && right.constant != null) { - final boolean overflow = settings.getNumericOverflow(); final Sort sort = promote.sort; if (sort == Sort.INT) { @@ -184,11 +173,9 @@ public final class EBinary extends AExpression { } else if (sort == Sort.LONG) { constant = (long)left.constant % (long)right.constant; } else if (sort == Sort.FLOAT) { - constant = overflow ? (float)left.constant % (float)right.constant : - org.elasticsearch.painless.Utility.remainderWithoutOverflow((float)left.constant, (float)right.constant); + constant = (float)left.constant % (float)right.constant; } else if (sort == Sort.DOUBLE) { - constant = overflow ? (double)left.constant % (double)right.constant : - org.elasticsearch.painless.Utility.remainderWithoutOverflow((double)left.constant, (double)right.constant); + constant = (double)left.constant % (double)right.constant; } else { throw new IllegalStateException(error("Illegal tree structure.")); } @@ -231,20 +218,14 @@ public final class EBinary extends AExpression { right = right.cast(settings, definition, variables); if (left.constant != null && right.constant != null) { - final boolean overflow = settings.getNumericOverflow(); - if (sort == Sort.INT) { - constant = overflow ? (int)left.constant + (int)right.constant : - Math.addExact((int)left.constant, (int)right.constant); + constant = (int)left.constant + (int)right.constant; } else if (sort == Sort.LONG) { - constant = overflow ? (long)left.constant + (long)right.constant : - Math.addExact((long)left.constant, (long)right.constant); + constant = (long)left.constant + (long)right.constant; } else if (sort == Sort.FLOAT) { - constant = overflow ? (float)left.constant + (float)right.constant : - org.elasticsearch.painless.Utility.addWithoutOverflow((float)left.constant, (float)right.constant); + constant = (float)left.constant + (float)right.constant; } else if (sort == Sort.DOUBLE) { - constant = overflow ? (double)left.constant + (double)right.constant : - org.elasticsearch.painless.Utility.addWithoutOverflow((double)left.constant, (double)right.constant); + constant = (double)left.constant + (double)right.constant; } else if (sort == Sort.STRING) { constant = "" + left.constant + right.constant; } else { @@ -273,21 +254,16 @@ public final class EBinary extends AExpression { right = right.cast(settings, definition, variables); if (left.constant != null && right.constant != null) { - final boolean overflow = settings.getNumericOverflow(); final Sort sort = promote.sort; if (sort == Sort.INT) { - constant = overflow ? (int)left.constant - (int)right.constant : - Math.subtractExact((int)left.constant, (int)right.constant); + constant = (int)left.constant - (int)right.constant; } else if (sort == Sort.LONG) { - constant = overflow ? (long)left.constant - (long)right.constant : - Math.subtractExact((long)left.constant, (long)right.constant); + constant = (long)left.constant - (long)right.constant; } else if (sort == Sort.FLOAT) { - constant = overflow ? (float)left.constant - (float)right.constant : - org.elasticsearch.painless.Utility.subtractWithoutOverflow((float)left.constant, (float)right.constant); + constant = (float)left.constant - (float)right.constant; } else if (sort == Sort.DOUBLE) { - constant = overflow ? (double)left.constant - (double)right.constant : - org.elasticsearch.painless.Utility.subtractWithoutOverflow((double)left.constant, (double)right.constant); + constant = (double)left.constant - (double)right.constant; } else { throw new IllegalStateException(error("Illegal tree structure.")); } @@ -519,7 +495,7 @@ public final class EBinary extends AExpression { left.write(settings, definition, adapter); right.write(settings, definition, adapter); - adapter.writeBinaryInstruction(settings, definition, location, actual, operation); + adapter.writeBinaryInstruction(definition, location, actual, operation); } adapter.writeBranch(tru, fals); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java index 763005d17ba..933295f9beb 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java @@ -44,7 +44,6 @@ public final class EChain extends AExpression { boolean cat = false; Type promote = null; - boolean exact = false; Cast there = null; Cast back = null; @@ -208,9 +207,6 @@ public final class EChain extends AExpression { expression = expression.cast(settings, definition, variables); - exact = !settings.getNumericOverflow() && - (operation == Operation.MUL || operation == Operation.DIV || operation == Operation.REM || - operation == Operation.ADD || operation == Operation.SUB); there = AnalyzerCaster.getLegalCast(definition, location, last.after, promote, false); back = AnalyzerCaster.getLegalCast(definition, location, promote, last.after, true); @@ -293,11 +289,9 @@ public final class EChain extends AExpression { adapter.writeCast(there); expression.write(settings, definition, adapter); - adapter.writeBinaryInstruction(settings, definition, location, promote, operation); + adapter.writeBinaryInstruction(definition, location, promote, operation); - if (!exact || !adapter.writeExactInstruction(definition, promote.sort, link.after.sort)) { - adapter.writeCast(back); - } + adapter.writeCast(back); if (link.load && !post) { adapter.writeDup(link.after.sort.size, link.size); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java index cbf76373136..409d1081ae9 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java @@ -31,8 +31,6 @@ import org.elasticsearch.painless.MethodWriter; import static org.elasticsearch.painless.WriterConstants.DEF_NEG_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_NOT_CALL; -import static org.elasticsearch.painless.WriterConstants.NEGATEEXACT_INT; -import static org.elasticsearch.painless.WriterConstants.NEGATEEXACT_LONG; /** * Represents a unary math expression. @@ -147,14 +145,13 @@ public final class EUnary extends AExpression { child = child.cast(settings, definition, variables); if (child.constant != null) { - final boolean overflow = settings.getNumericOverflow(); final Sort sort = promote.sort; if (sort == Sort.INT) { - constant = overflow ? -(int)child.constant : Math.negateExact((int)child.constant); + constant = -(int)child.constant; } else if (sort == Sort.LONG) { - constant = overflow ? -(long)child.constant : Math.negateExact((long)child.constant); + constant = -(long)child.constant; } else if (sort == Sort.FLOAT) { constant = -(float)child.constant; } else if (sort == Sort.DOUBLE) { @@ -211,17 +208,7 @@ public final class EUnary extends AExpression { if (sort == Sort.DEF) { adapter.invokeStatic(definition.getType("Def").type, DEF_NEG_CALL); } else { - if (settings.getNumericOverflow()) { - adapter.math(MethodWriter.NEG, type); - } else { - if (sort == Sort.INT) { - adapter.invokeStatic(definition.getType("Math").type, NEGATEEXACT_INT); - } else if (sort == Sort.LONG) { - adapter.invokeStatic(definition.getType("Math").type, NEGATEEXACT_LONG); - } else { - throw new IllegalStateException(error("Illegal tree structure.")); - } - } + adapter.math(MethodWriter.NEG, type); } } else if (operation != Operation.ADD) { throw new IllegalStateException(error("Illegal tree structure.")); diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowDisabledTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowDisabledTests.java deleted file mode 100644 index 7bec0b110df..00000000000 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowDisabledTests.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.painless; - -import java.util.Collections; -import java.util.Map; - -/** Tests floating point overflow with numeric overflow disabled */ -public class FloatOverflowDisabledTests extends ScriptTestCase { - - /** wire overflow to false for all tests */ - @Override - public Object exec(String script, Map vars) { - return exec(script, vars, Collections.singletonMap(CompilerSettings.NUMERIC_OVERFLOW, "false")); - } - - public void testAssignmentAdditionOverflow() { - // float - try { - exec("float x = 3.4028234663852886E38f; x += 3.4028234663852886E38f; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("float x = -3.4028234663852886E38f; x += -3.4028234663852886E38f; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - - // double - try { - exec("double x = 1.7976931348623157E308; x += 1.7976931348623157E308; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("double x = -1.7976931348623157E308; x += -1.7976931348623157E308; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testAssignmentSubtractionOverflow() { - // float - try { - exec("float x = 3.4028234663852886E38f; x -= -3.4028234663852886E38f; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("float x = -3.4028234663852886E38f; x -= 3.4028234663852886E38f; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - - // double - try { - exec("double x = 1.7976931348623157E308; x -= -1.7976931348623157E308; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("double x = -1.7976931348623157E308; x -= 1.7976931348623157E308; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testAssignmentMultiplicationOverflow() { - // float - try { - exec("float x = 3.4028234663852886E38f; x *= 3.4028234663852886E38f; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("float x = 3.4028234663852886E38f; x *= -3.4028234663852886E38f; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - - // double - try { - exec("double x = 1.7976931348623157E308; x *= 1.7976931348623157E308; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("double x = 1.7976931348623157E308; x *= -1.7976931348623157E308; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testAssignmentDivisionOverflow() { - // float - try { - exec("float x = 3.4028234663852886E38f; x /= 1.401298464324817E-45f; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("float x = 3.4028234663852886E38f; x /= -1.401298464324817E-45f; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("float x = 1.0f; x /= 0.0f; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - - // double - try { - exec("double x = 1.7976931348623157E308; x /= 4.9E-324; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("double x = 1.7976931348623157E308; x /= -4.9E-324; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("double x = 1.0f; x /= 0.0; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testAddition() throws Exception { - try { - exec("float x = 3.4028234663852886E38f; float y = 3.4028234663852886E38f; return x + y;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("double x = 1.7976931348623157E308; double y = 1.7976931348623157E308; return x + y;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testAdditionConst() throws Exception { - try { - exec("return 3.4028234663852886E38f + 3.4028234663852886E38f;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("return 1.7976931348623157E308 + 1.7976931348623157E308;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testSubtraction() throws Exception { - try { - exec("float x = -3.4028234663852886E38f; float y = 3.4028234663852886E38f; return x - y;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("double x = -1.7976931348623157E308; double y = 1.7976931348623157E308; return x - y;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testSubtractionConst() throws Exception { - try { - exec("return -3.4028234663852886E38f - 3.4028234663852886E38f;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("return -1.7976931348623157E308 - 1.7976931348623157E308;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testMultiplication() throws Exception { - try { - exec("float x = 3.4028234663852886E38f; float y = 3.4028234663852886E38f; return x * y;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("double x = 1.7976931348623157E308; double y = 1.7976931348623157E308; return x * y;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testMultiplicationConst() throws Exception { - try { - exec("return 3.4028234663852886E38f * 3.4028234663852886E38f;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("return 1.7976931348623157E308 * 1.7976931348623157E308;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testDivision() throws Exception { - try { - exec("float x = 3.4028234663852886E38f; float y = 1.401298464324817E-45f; return x / y;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("float x = 1.0f; float y = 0.0f; return x / y;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("double x = 1.7976931348623157E308; double y = 4.9E-324; return x / y;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("double x = 1.0; double y = 0.0; return x / y;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testDivisionConst() throws Exception { - try { - exec("return 3.4028234663852886E38f / 1.401298464324817E-45f;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("return 1.0f / 0.0f;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("return 1.7976931348623157E308 / 4.9E-324;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("return 1.0 / 0.0;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testDivisionNaN() throws Exception { - // float division, constant division, and assignment - try { - exec("float x = 0f; float y = 0f; return x / y;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("return 0f / 0f;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("float x = 0f; x /= 0f; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - - // double division, constant division, and assignment - try { - exec("double x = 0.0; double y = 0.0; return x / y;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("return 0.0 / 0.0;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("double x = 0.0; x /= 0.0; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testRemainderNaN() throws Exception { - // float division, constant division, and assignment - try { - exec("float x = 1f; float y = 0f; return x % y;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("return 1f % 0f;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("float x = 1f; x %= 0f; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - - // double division, constant division, and assignment - try { - exec("double x = 1.0; double y = 0.0; return x % y;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("return 1.0 % 0.0;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - try { - exec("double x = 1.0; x %= 0.0; return x;"); - fail("didn't hit expected exception"); - } catch (ArithmeticException expected) {} - } -} diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowEnabledTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowTests.java similarity index 94% rename from modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowEnabledTests.java rename to modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowTests.java index ccfd2232e88..4b3eb8f0e7f 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowEnabledTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/FloatOverflowTests.java @@ -19,17 +19,8 @@ package org.elasticsearch.painless; -import java.util.Collections; -import java.util.Map; - -/** Tests floating point overflow with numeric overflow enabled */ -public class FloatOverflowEnabledTests extends ScriptTestCase { - - /** wire overflow to true for all tests */ - @Override - public Object exec(String script, Map vars) { - return exec(script, vars, Collections.singletonMap(CompilerSettings.NUMERIC_OVERFLOW, "true")); - } +/** Tests floating point overflow cases */ +public class FloatOverflowTests extends ScriptTestCase { public void testAssignmentAdditionOverflow() { // float diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowDisabledTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowDisabledTests.java deleted file mode 100644 index f4adcfce878..00000000000 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowDisabledTests.java +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.painless; - -import java.util.Collections; -import java.util.Map; - -/** Tests integer overflow with numeric overflow disabled */ -public class IntegerOverflowDisabledTests extends ScriptTestCase { - - /** wire overflow to true for all tests */ - @Override - public Object exec(String script, Map vars) { - return exec(script, vars, Collections.singletonMap(CompilerSettings.NUMERIC_OVERFLOW, "false")); - } - - public void testAssignmentAdditionOverflow() { - // byte - try { - exec("byte x = 0; x += 128; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("byte x = 0; x += -129; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - // short - try { - exec("short x = 0; x += 32768; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("byte x = 0; x += -32769; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - // char - try { - exec("char x = 0; x += 65536; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("char x = 0; x += -65536; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - // int - try { - exec("int x = 1; x += 2147483647; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("int x = -2; x += -2147483647; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - // long - try { - exec("long x = 1; x += 9223372036854775807L; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("long x = -2; x += -9223372036854775807L; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testAssignmentSubtractionOverflow() { - // byte - try { - exec("byte x = 0; x -= -128; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("byte x = 0; x -= 129; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - // short - try { - exec("short x = 0; x -= -32768; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("byte x = 0; x -= 32769; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - // char - try { - exec("char x = 0; x -= -65536; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("char x = 0; x -= 65536; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - // int - try { - exec("int x = 1; x -= -2147483647; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("int x = -2; x -= 2147483647; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - // long - try { - exec("long x = 1; x -= -9223372036854775807L; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("long x = -2; x -= 9223372036854775807L; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testAssignmentMultiplicationOverflow() { - // byte - try { - exec("byte x = 2; x *= 128; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("byte x = 2; x *= -128; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - // char - try { - exec("char x = 2; x *= 65536; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("char x = 2; x *= -65536; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - // int - try { - exec("int x = 2; x *= 2147483647; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("int x = 2; x *= -2147483647; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - // long - try { - exec("long x = 2; x *= 9223372036854775807L; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("long x = 2; x *= -9223372036854775807L; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testAssignmentDivisionOverflow() { - // byte - try { - exec("byte x = (byte) -128; x /= -1; return x;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - - // short - try { - exec("short x = (short) -32768; x /= -1; return x;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - - // cannot happen for char: unsigned - - // int - try { - exec("int x = -2147483647 - 1; x /= -1; return x;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - - // long - try { - exec("long x = -9223372036854775807L - 1L; x /=-1L; return x;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - } - - public void testIncrementOverFlow() throws Exception { - // byte - try { - exec("byte x = 127; ++x; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("byte x = 127; x++; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("byte x = (byte) -128; --x; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("byte x = (byte) -128; x--; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - // short - try { - exec("short x = 32767; ++x; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("short x = 32767; x++; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("short x = (short) -32768; --x; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("short x = (short) -32768; x--; return x;"); - } catch (ArithmeticException expected) {} - - // char - try { - exec("char x = 65535; ++x; return x;"); - } catch (ArithmeticException expected) {} - - try { - exec("char x = 65535; x++; return x;"); - } catch (ArithmeticException expected) {} - - try { - exec("char x = (char) 0; --x; return x;"); - } catch (ArithmeticException expected) {} - - try { - exec("char x = (char) 0; x--; return x;"); - } catch (ArithmeticException expected) {} - - // int - try { - exec("int x = 2147483647; ++x; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("int x = 2147483647; x++; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("int x = (int) -2147483648L; --x; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("int x = (int) -2147483648L; x--; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - // long - try { - exec("long x = 9223372036854775807L; ++x; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("long x = 9223372036854775807L; x++; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("long x = -9223372036854775807L - 1L; --x; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("long x = -9223372036854775807L - 1L; x--; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testAddition() throws Exception { - try { - exec("int x = 2147483647; int y = 2147483647; return x + y;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - - try { - exec("long x = 9223372036854775807L; long y = 9223372036854775807L; return x + y;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - } - - public void testAdditionConst() throws Exception { - try { - exec("return 2147483647 + 2147483647;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - - try { - exec("return 9223372036854775807L + 9223372036854775807L;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - } - - - public void testSubtraction() throws Exception { - try { - exec("int x = -10; int y = 2147483647; return x - y;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - - try { - exec("long x = -10L; long y = 9223372036854775807L; return x - y;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - } - - public void testSubtractionConst() throws Exception { - try { - exec("return -10 - 2147483647;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - - try { - exec("return -10L - 9223372036854775807L;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - } - - public void testMultiplication() throws Exception { - try { - exec("int x = 2147483647; int y = 2147483647; return x * y;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - - try { - exec("long x = 9223372036854775807L; long y = 9223372036854775807L; return x * y;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - } - - public void testMultiplicationConst() throws Exception { - try { - exec("return 2147483647 * 2147483647;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - - try { - exec("return 9223372036854775807L * 9223372036854775807L;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - } - - public void testDivision() throws Exception { - try { - exec("int x = -2147483647 - 1; int y = -1; return x / y;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - - try { - exec("long x = -9223372036854775808L; long y = -1L; return x / y;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - } - - public void testDivisionConst() throws Exception { - try { - exec("return (-2147483648) / -1;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - - try { - exec("return (-9223372036854775808L) / -1L;"); - fail("should have hit exception"); - } catch (ArithmeticException expected) {} - } - - public void testNegationOverflow() throws Exception { - try { - exec("int x = -2147483648; x = -x; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("long x = -9223372036854775808L; x = -x; return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testNegationOverflowConst() throws Exception { - try { - exec("int x = -(-2147483648); return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - exec("long x = -(-9223372036854775808L); return x;"); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } -} diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowEnabledTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowTests.java similarity index 95% rename from modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowEnabledTests.java rename to modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowTests.java index 41b3f857c0a..1165547bf5a 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowEnabledTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/IntegerOverflowTests.java @@ -19,17 +19,8 @@ package org.elasticsearch.painless; -import java.util.Collections; -import java.util.Map; - -/** Tests integer overflow with numeric overflow enabled */ -public class IntegerOverflowEnabledTests extends ScriptTestCase { - - /** wire overflow to true for all tests */ - @Override - public Object exec(String script, Map vars) { - return exec(script, vars, Collections.singletonMap(CompilerSettings.NUMERIC_OVERFLOW, "true")); - } +/** Tests integer overflow cases */ +public class IntegerOverflowTests extends ScriptTestCase { public void testAssignmentAdditionOverflow() { // byte diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ScriptTestCase.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ScriptTestCase.java index 2ccd2f1460a..c3ce127034e 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ScriptTestCase.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ScriptTestCase.java @@ -48,7 +48,7 @@ public abstract class ScriptTestCase extends ESTestCase { /** Compiles and returns the result of {@code script} with access to {@code vars} */ public Object exec(String script, Map vars) { - return exec(script, vars, Collections.singletonMap(CompilerSettings.NUMERIC_OVERFLOW, Boolean.toString(random().nextBoolean()))); + return exec(script, vars, Collections.emptyMap()); } /** Compiles and returns the result of {@code script} with access to {@code vars} and compile-time parameters */ diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/UtilityTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/UtilityTests.java deleted file mode 100644 index ba476fac7f2..00000000000 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/UtilityTests.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.painless; - -import org.elasticsearch.test.ESTestCase; - -/** - * Tests utility methods (typically built-ins) - */ -public class UtilityTests extends ESTestCase { - - public void testDivideWithoutOverflowInt() { - assertEquals(5 / 2, Utility.divideWithoutOverflow(5, 2)); - - try { - Utility.divideWithoutOverflow(Integer.MIN_VALUE, -1); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - Utility.divideWithoutOverflow(5, 0); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testDivideWithoutOverflowLong() { - assertEquals(5L / 2L, Utility.divideWithoutOverflow(5L, 2L)); - - try { - Utility.divideWithoutOverflow(Long.MIN_VALUE, -1L); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - Utility.divideWithoutOverflow(5L, 0L); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testToByteExact() { - for (int b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) { - assertEquals((byte)b, Utility.toByteExact(b)); - } - - try { - Utility.toByteExact(Byte.MIN_VALUE - 1); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - Utility.toByteExact(Byte.MAX_VALUE + 1); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testToShortExact() { - for (int s = Short.MIN_VALUE; s < Short.MAX_VALUE; s++) { - assertEquals((short)s, Utility.toShortExact(s)); - } - - try { - Utility.toShortExact(Short.MIN_VALUE - 1); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - Utility.toShortExact(Short.MAX_VALUE + 1); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testToCharExact() { - for (int c = Character.MIN_VALUE; c < Character.MAX_VALUE; c++) { - assertEquals((char)c, Utility.toCharExact(c)); - } - - try { - Utility.toCharExact(Character.MIN_VALUE - 1); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - Utility.toCharExact(Character.MAX_VALUE + 1); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testAddWithoutOverflowFloat() { - assertEquals(10F, Utility.addWithoutOverflow(5F, 5F), 0F); - assertTrue(Float.isNaN(Utility.addWithoutOverflow(5F, Float.NaN))); - assertTrue(Float.isNaN(Utility.addWithoutOverflow(Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY))); - - try { - Utility.addWithoutOverflow(Float.MAX_VALUE, Float.MAX_VALUE); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - Utility.addWithoutOverflow(-Float.MAX_VALUE, -Float.MAX_VALUE); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testAddWithoutOverflowDouble() { - assertEquals(10D, Utility.addWithoutOverflow(5D, 5D), 0D); - assertTrue(Double.isNaN(Utility.addWithoutOverflow(5D, Double.NaN))); - assertTrue(Double.isNaN(Utility.addWithoutOverflow(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY))); - - try { - Utility.addWithoutOverflow(Double.MAX_VALUE, Double.MAX_VALUE); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - Utility.addWithoutOverflow(-Double.MAX_VALUE, -Double.MAX_VALUE); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testSubtractWithoutOverflowFloat() { - assertEquals(5F, Utility.subtractWithoutOverflow(10F, 5F), 0F); - assertTrue(Float.isNaN(Utility.subtractWithoutOverflow(5F, Float.NaN))); - assertTrue(Float.isNaN(Utility.subtractWithoutOverflow(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY))); - - try { - Utility.subtractWithoutOverflow(Float.MAX_VALUE, -Float.MAX_VALUE); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - Utility.subtractWithoutOverflow(-Float.MAX_VALUE, Float.MAX_VALUE); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testSubtractWithoutOverflowDouble() { - assertEquals(5D, Utility.subtractWithoutOverflow(10D, 5D), 0D); - assertTrue(Double.isNaN(Utility.subtractWithoutOverflow(5D, Double.NaN))); - assertTrue(Double.isNaN(Utility.subtractWithoutOverflow(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY))); - - try { - Utility.subtractWithoutOverflow(Double.MAX_VALUE, -Double.MAX_VALUE); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - Utility.subtractWithoutOverflow(-Double.MAX_VALUE, Double.MAX_VALUE); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testMultiplyWithoutOverflowFloat() { - assertEquals(25F, Utility.multiplyWithoutOverflow(5F, 5F), 0F); - assertTrue(Float.isNaN(Utility.multiplyWithoutOverflow(5F, Float.NaN))); - assertEquals(Float.POSITIVE_INFINITY, Utility.multiplyWithoutOverflow(5F, Float.POSITIVE_INFINITY), 0F); - - try { - Utility.multiplyWithoutOverflow(Float.MAX_VALUE, Float.MAX_VALUE); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testMultiplyWithoutOverflowDouble() { - assertEquals(25D, Utility.multiplyWithoutOverflow(5D, 5D), 0D); - assertTrue(Double.isNaN(Utility.multiplyWithoutOverflow(5D, Double.NaN))); - assertEquals(Double.POSITIVE_INFINITY, Utility.multiplyWithoutOverflow(5D, Double.POSITIVE_INFINITY), 0D); - - try { - Utility.multiplyWithoutOverflow(Double.MAX_VALUE, Double.MAX_VALUE); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testDivideWithoutOverflowFloat() { - assertEquals(5F, Utility.divideWithoutOverflow(25F, 5F), 0F); - assertTrue(Float.isNaN(Utility.divideWithoutOverflow(5F, Float.NaN))); - assertEquals(Float.POSITIVE_INFINITY, Utility.divideWithoutOverflow(Float.POSITIVE_INFINITY, 5F), 0F); - - try { - Utility.divideWithoutOverflow(Float.MAX_VALUE, Float.MIN_VALUE); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - Utility.divideWithoutOverflow(0F, 0F); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - Utility.divideWithoutOverflow(5F, 0F); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testDivideWithoutOverflowDouble() { - assertEquals(5D, Utility.divideWithoutOverflow(25D, 5D), 0D); - assertTrue(Double.isNaN(Utility.divideWithoutOverflow(5D, Double.NaN))); - assertEquals(Double.POSITIVE_INFINITY, Utility.divideWithoutOverflow(Double.POSITIVE_INFINITY, 5D), 0D); - - try { - Utility.divideWithoutOverflow(Double.MAX_VALUE, Double.MIN_VALUE); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - Utility.divideWithoutOverflow(0D, 0D); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - - try { - Utility.divideWithoutOverflow(5D, 0D); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testRemainderWithoutOverflowFloat() { - assertEquals(1F, Utility.remainderWithoutOverflow(25F, 4F), 0F); - - try { - Utility.remainderWithoutOverflow(5F, 0F); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } - - public void testRemainderWithoutOverflowDouble() { - assertEquals(1D, Utility.remainderWithoutOverflow(25D, 4D), 0D); - - try { - Utility.remainderWithoutOverflow(5D, 0D); - fail("did not get expected exception"); - } catch (ArithmeticException expected) {} - } -} From a569130368deca90ff939708de8f001ff548fd72 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Thu, 19 May 2016 15:28:59 -0400 Subject: [PATCH 03/22] fix typo --- .../src/main/java/org/elasticsearch/painless/Def.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java index 9226fc3f098..7cc3d2f870e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java @@ -52,7 +52,7 @@ public final class Def { // TODO: Once Java has a factory for those in java.lang.invoke.MethodHandles, use it: /** Helper class for isolating MethodHandles and methods to get the length of arrays - * (to emulate a "arraystore" byteoode using MethodHandles). + * (to emulate a "arraystore" bytecode using MethodHandles). * This should really be a method in {@link MethodHandles} class! */ private static final class ArrayLengthHelper { From 0ee726ed0dfe352dc8362149ca80f4969088a607 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Thu, 19 May 2016 15:35:26 -0400 Subject: [PATCH 04/22] nuke eclipse warnings --- .../src/main/java/org/elasticsearch/painless/Def.java | 10 ++++++++++ .../painless/PainlessScriptEngineService.java | 2 +- .../java/org/elasticsearch/painless/node/EUnary.java | 1 - .../org/elasticsearch/painless/NeedsScoreTests.java | 1 + 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java index 7cc3d2f870e..e5967501664 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java @@ -72,14 +72,24 @@ public final class Def { private static final MethodHandle OBJECT_ARRAY_MH = ARRAY_TYPE_MH_MAPPING.get(Object[].class); + // NOTE: the following are actually used, javac just does not know :) + @SuppressWarnings("unused") static int getArrayLength(final boolean[] array) { return array.length; } + @SuppressWarnings("unused") static int getArrayLength(final byte[] array) { return array.length; } + @SuppressWarnings("unused") static int getArrayLength(final short[] array) { return array.length; } + @SuppressWarnings("unused") static int getArrayLength(final int[] array) { return array.length; } + @SuppressWarnings("unused") static int getArrayLength(final long[] array) { return array.length; } + @SuppressWarnings("unused") static int getArrayLength(final char[] array) { return array.length; } + @SuppressWarnings("unused") static int getArrayLength(final float[] array) { return array.length; } + @SuppressWarnings("unused") static int getArrayLength(final double[] array) { return array.length; } + @SuppressWarnings("unused") static int getArrayLength(final Object[] array) { return array.length; } static MethodHandle arrayLengthGetter(Class arrayType) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java index 4c627d08eca..72a657cd7f0 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessScriptEngineService.java @@ -204,7 +204,7 @@ public final class PainlessScriptEngineService extends AbstractComponent impleme * Action taken when the engine is closed. */ @Override - public void close() throws IOException { + public void close() { // Nothing to do. } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java index 409d1081ae9..7e52790fa50 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java @@ -147,7 +147,6 @@ public final class EUnary extends AExpression { if (child.constant != null) { final Sort sort = promote.sort; - if (sort == Sort.INT) { constant = -(int)child.constant; } else if (sort == Sort.LONG) { diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/NeedsScoreTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/NeedsScoreTests.java index 4b56d9751b6..3fe071c5221 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/NeedsScoreTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/NeedsScoreTests.java @@ -60,6 +60,7 @@ public class NeedsScoreTests extends ESSingleNodeTestCase { ss = service.search(new CompiledScript(ScriptType.INLINE, "randomName", "painless", compiled), lookup, Collections.emptyMap()); assertTrue(ss.needsScores()); + service.close(); } } From afa9ebad28095ea91a615acdc8a023dc734c377c Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Thu, 19 May 2016 16:03:11 -0400 Subject: [PATCH 05/22] dce --- .../main/java/org/elasticsearch/painless/Definition.java | 8 +++----- .../main/java/org/elasticsearch/painless/node/LField.java | 8 -------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java index 68fc3a32262..bde6063cfe1 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java @@ -174,17 +174,15 @@ public final class Definition { public static final class Field { public final String name; public final Struct owner; - public final Type generic; public final Type type; public final java.lang.reflect.Field reflect; public final MethodHandle getter; public final MethodHandle setter; - private Field(final String name, final Struct owner, final Type generic, final Type type, + private Field(final String name, final Struct owner, final Type type, final java.lang.reflect.Field reflect, final MethodHandle getter, final MethodHandle setter) { this.name = name; this.owner = owner; - this.generic = generic; this.type = type; this.reflect = reflect; this.getter = getter; @@ -1048,7 +1046,7 @@ public final class Definition { " not found for class [" + owner.clazz.getName() + "]."); } - final Field field = new Field(name, owner, type, type, reflect, getter, setter); + final Field field = new Field(name, owner, type, reflect, getter, setter); if (isStatic) { // require that all static fields are static final @@ -1138,7 +1136,7 @@ public final class Definition { } owner.members.put(field.name, - new Field(field.name, owner, field.type, field.generic, reflect, getter, setter)); + new Field(field.name, owner, field.type, reflect, getter, setter)); } } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LField.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LField.java index 06f820eba26..3ec456c69a4 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LField.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LField.java @@ -107,16 +107,8 @@ public final class LField extends ALink { void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { if (java.lang.reflect.Modifier.isStatic(field.reflect.getModifiers())) { adapter.getStatic(field.owner.type, field.reflect.getName(), field.type.type); - - if (!field.generic.clazz.equals(field.type.clazz)) { - adapter.checkCast(field.generic.type); - } } else { adapter.getField(field.owner.type, field.reflect.getName(), field.type.type); - - if (!field.generic.clazz.equals(field.type.clazz)) { - adapter.checkCast(field.generic.type); - } } } From cfe555d216120818b4823e967659b13a30f3b3a5 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Fri, 20 May 2016 00:46:05 +0200 Subject: [PATCH 06/22] move unused @SuppressWarnings one level up --- .../src/main/java/org/elasticsearch/painless/Def.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java index e5967501664..889328e58db 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java @@ -55,6 +55,7 @@ public final class Def { * (to emulate a "arraystore" bytecode using MethodHandles). * This should really be a method in {@link MethodHandles} class! */ + @SuppressWarnings("unused") // getArrayLength() methods are are actually used, javac just does not know :) private static final class ArrayLengthHelper { private static final Lookup PRIV_LOOKUP = MethodHandles.lookup(); @@ -72,24 +73,14 @@ public final class Def { private static final MethodHandle OBJECT_ARRAY_MH = ARRAY_TYPE_MH_MAPPING.get(Object[].class); - // NOTE: the following are actually used, javac just does not know :) - @SuppressWarnings("unused") static int getArrayLength(final boolean[] array) { return array.length; } - @SuppressWarnings("unused") static int getArrayLength(final byte[] array) { return array.length; } - @SuppressWarnings("unused") static int getArrayLength(final short[] array) { return array.length; } - @SuppressWarnings("unused") static int getArrayLength(final int[] array) { return array.length; } - @SuppressWarnings("unused") static int getArrayLength(final long[] array) { return array.length; } - @SuppressWarnings("unused") static int getArrayLength(final char[] array) { return array.length; } - @SuppressWarnings("unused") static int getArrayLength(final float[] array) { return array.length; } - @SuppressWarnings("unused") static int getArrayLength(final double[] array) { return array.length; } - @SuppressWarnings("unused") static int getArrayLength(final Object[] array) { return array.length; } static MethodHandle arrayLengthGetter(Class arrayType) { From 3962553551ed2c8366161e26da2d18c963eabc0d Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Thu, 19 May 2016 18:51:55 -0700 Subject: [PATCH 07/22] Removed user-facing boxing. --- .../painless/AnalyzerCaster.java | 189 +++++++---------- .../elasticsearch/painless/Definition.java | 198 +----------------- .../elasticsearch/painless/node/EBinary.java | 18 +- .../elasticsearch/painless/node/EChain.java | 14 +- .../elasticsearch/painless/node/EComp.java | 12 +- .../elasticsearch/painless/node/EUnary.java | 6 +- .../painless/DefOperationTests.java | 158 +++++++------- 7 files changed, 190 insertions(+), 405 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java index d6f099e47f9..398dc0a7a61 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java @@ -115,29 +115,25 @@ public final class AnalyzerCaster { } } - public static Type promoteNumeric(final Definition definition, final Type from, final boolean decimal, final boolean primitive) { + public static Type promoteNumeric(final Definition definition, final Type from, final boolean decimal) { final Sort sort = from.sort; if (sort == Sort.DEF) { return definition.getType("def"); - } else if ((sort == Sort.DOUBLE || sort == Sort.DOUBLE_OBJ) && decimal) { - return primitive ? definition.getType("double") : definition.getType("Double"); - } else if ((sort == Sort.FLOAT || sort == Sort.FLOAT_OBJ) && decimal) { - return primitive ? definition.getType("float") : definition.getType("Float"); - } else if (sort == Sort.LONG || sort == Sort.LONG_OBJ) { - return primitive ? definition.getType("long") : definition.getType("Long"); - } else if (sort == Sort.INT || sort == Sort.INT_OBJ || - sort == Sort.CHAR || sort == Sort.CHAR_OBJ || - sort == Sort.SHORT || sort == Sort.SHORT_OBJ || - sort == Sort.BYTE || sort == Sort.BYTE_OBJ) { - return primitive ? definition.getType("int") : definition.getType("Integer"); + } else if ((sort == Sort.DOUBLE) && decimal) { + return definition.getType("double"); + } else if ((sort == Sort.FLOAT) && decimal) { + return definition.getType("float"); + } else if (sort == Sort.LONG) { + return definition.getType("long"); + } else if (sort == Sort.INT || sort == Sort.CHAR || sort == Sort.SHORT || sort == Sort.BYTE) { + return definition.getType("int"); } return null; } - public static Type promoteNumeric(final Definition definition, - final Type from0, final Type from1, final boolean decimal, final boolean primitive) { + public static Type promoteNumeric(final Definition definition, final Type from0, final Type from1, final boolean decimal) { final Sort sort0 = from0.sort; final Sort sort1 = from1.sort; @@ -146,26 +142,20 @@ public final class AnalyzerCaster { } if (decimal) { - if (sort0 == Sort.DOUBLE || sort0 == Sort.DOUBLE_OBJ || - sort1 == Sort.DOUBLE || sort1 == Sort.DOUBLE_OBJ) { - return primitive ? definition.getType("double") : definition.getType("Double"); - } else if (sort0 == Sort.FLOAT || sort0 == Sort.FLOAT_OBJ || sort1 == Sort.FLOAT || sort1 == Sort.FLOAT_OBJ) { - return primitive ? definition.getType("float") : definition.getType("Float"); + if (sort0 == Sort.DOUBLE || sort1 == Sort.DOUBLE) { + return definition.getType("double"); + } else if (sort0 == Sort.FLOAT || sort1 == Sort.FLOAT) { + return definition.getType("float"); } } - if (sort0 == Sort.LONG || sort0 == Sort.LONG_OBJ || - sort1 == Sort.LONG || sort1 == Sort.LONG_OBJ) { - return primitive ? definition.getType("long") : definition.getType("Long"); - } else if (sort0 == Sort.INT || sort0 == Sort.INT_OBJ || - sort1 == Sort.INT || sort1 == Sort.INT_OBJ || - sort0 == Sort.CHAR || sort0 == Sort.CHAR_OBJ || - sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ || - sort0 == Sort.SHORT || sort0 == Sort.SHORT_OBJ || - sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ || - sort0 == Sort.BYTE || sort0 == Sort.BYTE_OBJ || - sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { - return primitive ? definition.getType("int") : definition.getType("Integer"); + if (sort0 == Sort.LONG || sort1 == Sort.LONG) { + return definition.getType("long"); + } else if (sort0 == Sort.INT || sort1 == Sort.INT || + sort0 == Sort.CHAR || sort1 == Sort.CHAR || + sort0 == Sort.SHORT || sort1 == Sort.SHORT || + sort0 == Sort.BYTE || sort1 == Sort.BYTE) { + return definition.getType("int"); } return null; @@ -179,7 +169,7 @@ public final class AnalyzerCaster { return definition.getType("String"); } - return promoteNumeric(definition, from0, from1, true, true); + return promoteNumeric(definition, from0, from1, true); } public static Type promoteXor(final Definition definition, final Type from0, final Type from1) { @@ -190,7 +180,7 @@ public final class AnalyzerCaster { return definition.getType("boolean"); } - return promoteNumeric(definition, from0, from1, false, true); + return promoteNumeric(definition, from0, from1, false); } public static Type promoteEquality(final Definition definition, final Type from0, final Type from1) { @@ -201,34 +191,13 @@ public final class AnalyzerCaster { return definition.getType("def"); } - final boolean primitive = sort0.primitive && sort1.primitive; - - if (sort0.bool && sort1.bool) { - return primitive ? definition.getType("boolean") : definition.getType("Boolean"); - } - - if (sort0.numeric && sort1.numeric) { - return promoteNumeric(definition, from0, from1, true, primitive); - } - - return definition.getType("Object"); - } - - public static Type promoteReference(final Definition definition, final Type from0, final Type from1) { - final Sort sort0 = from0.sort; - final Sort sort1 = from1.sort; - - if (sort0 == Sort.DEF || sort1 == Sort.DEF) { - return definition.getType("def"); - } - if (sort0.primitive && sort1.primitive) { if (sort0.bool && sort1.bool) { return definition.getType("boolean"); } if (sort0.numeric && sort1.numeric) { - return promoteNumeric(definition, from0, from1, true, true); + return promoteNumeric(definition, from0, from1, true); } } @@ -248,123 +217,121 @@ public final class AnalyzerCaster { return definition.getType("def"); } - final boolean primitive = sort0.primitive && sort1.primitive; + if (sort0.primitive && sort1.primitive) { + if (sort0.bool && sort1.bool) { + return definition.getType("boolean"); + } - if (sort0.bool && sort1.bool) { - return primitive ? definition.getType("boolean") : definition.getType("Boolean"); - } - - if (sort0.numeric && sort1.numeric) { - if (sort0 == Sort.DOUBLE || sort0 == Sort.DOUBLE_OBJ || sort1 == Sort.DOUBLE || sort1 == Sort.DOUBLE_OBJ) { - return primitive ? definition.getType("double") : definition.getType("Double"); - } else if (sort0 == Sort.FLOAT || sort0 == Sort.FLOAT_OBJ || sort1 == Sort.FLOAT || sort1 == Sort.FLOAT_OBJ) { - return primitive ? definition.getType("float") : definition.getType("Float"); - } else if (sort0 == Sort.LONG || sort0 == Sort.LONG_OBJ || sort1 == Sort.LONG || sort1 == Sort.LONG_OBJ) { - return sort0.primitive && sort1.primitive ? definition.getType("long") : definition.getType("Long"); + if (sort0 == Sort.DOUBLE || sort1 == Sort.DOUBLE) { + return definition.getType("double"); + } else if (sort0 == Sort.FLOAT || sort1 == Sort.FLOAT) { + return definition.getType("float"); + } else if (sort0 == Sort.LONG || sort1 == Sort.LONG) { + definition.getType("long"); } else { - if (sort0 == Sort.BYTE || sort0 == Sort.BYTE_OBJ) { - if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); - } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { + if (sort0 == Sort.BYTE) { + if (sort1 == Sort.BYTE) { + return definition.getType("byte"); + } else if (sort1 == Sort.SHORT) { if (const1 != null) { final short constant = (short)const1; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return definition.getType("byte"); } } - return primitive ? definition.getType("short") : definition.getType("Short"); - } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { - return primitive ? definition.getType("int") : definition.getType("Integer"); - } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { + return definition.getType("short"); + } else if (sort1 == Sort.CHAR) { + return definition.getType("int"); + } else if (sort1 == Sort.INT) { if (const1 != null) { final int constant = (int)const1; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return definition.getType("byte"); } } - return primitive ? definition.getType("int") : definition.getType("Integer"); + return definition.getType("int"); } - } else if (sort0 == Sort.SHORT || sort0 == Sort.SHORT_OBJ) { - if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { + } else if (sort0 == Sort.SHORT) { + if (sort1 == Sort.BYTE) { if (const0 != null) { final short constant = (short)const0; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return definition.getType("byte"); } } - return primitive ? definition.getType("short") : definition.getType("Short"); - } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { - return primitive ? definition.getType("short") : definition.getType("Short"); - } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { - return primitive ? definition.getType("int") : definition.getType("Integer"); - } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { + return definition.getType("short"); + } else if (sort1 == Sort.SHORT) { + return definition.getType("short"); + } else if (sort1 == Sort.CHAR) { + return definition.getType("int"); + } else if (sort1 == Sort.INT) { if (const1 != null) { final int constant = (int)const1; if (constant <= Short.MAX_VALUE && constant >= Short.MIN_VALUE) { - return primitive ? definition.getType("short") : definition.getType("Short"); + return definition.getType("short"); } } - return primitive ? definition.getType("int") : definition.getType("Integer"); + return definition.getType("int"); } - } else if (sort0 == Sort.CHAR || sort0 == Sort.CHAR_OBJ) { - if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { - return primitive ? definition.getType("int") : definition.getType("Integer"); - } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { - return primitive ? definition.getType("int") : definition.getType("Integer"); - } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { - return primitive ? definition.getType("char") : definition.getType("Character"); - } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { + } else if (sort0 == Sort.CHAR) { + if (sort1 == Sort.BYTE) { + return definition.getType("int"); + } else if (sort1 == Sort.SHORT) { + return definition.getType("int"); + } else if (sort1 == Sort.CHAR) { + return definition.getType("char"); + } else if (sort1 == Sort.INT) { if (const1 != null) { final int constant = (int)const1; if (constant <= Character.MAX_VALUE && constant >= Character.MIN_VALUE) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return definition.getType("byte"); } } - return primitive ? definition.getType("int") : definition.getType("Integer"); + return definition.getType("int"); } - } else if (sort0 == Sort.INT || sort0 == Sort.INT_OBJ) { - if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { + } else if (sort0 == Sort.INT) { + if (sort1 == Sort.BYTE) { if (const0 != null) { final int constant = (int)const0; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return definition.getType("byte"); } } - return primitive ? definition.getType("int") : definition.getType("Integer"); - } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { + return definition.getType("int"); + } else if (sort1 == Sort.SHORT) { if (const0 != null) { final int constant = (int)const0; if (constant <= Short.MAX_VALUE && constant >= Short.MIN_VALUE) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return definition.getType("byte"); } } - return primitive ? definition.getType("int") : definition.getType("Integer"); - } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { + return definition.getType("int"); + } else if (sort1 == Sort.CHAR) { if (const0 != null) { final int constant = (int)const0; if (constant <= Character.MAX_VALUE && constant >= Character.MIN_VALUE) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return definition.getType("byte"); } } - return primitive ? definition.getType("int") : definition.getType("Integer"); - } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { - return primitive ? definition.getType("int") : definition.getType("Integer"); + return definition.getType("int"); + } else if (sort1 == Sort.INT) { + return definition.getType("int"); } } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java index bde6063cfe1..95d169cb886 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java @@ -524,7 +524,7 @@ public final class Definition { Type floatobjType = getType("Float"); Type doubleobjType = getType("Double"); Type stringType = getType("String"); - + addTransform(booleanType, objectType, "Boolean", "valueOf", true, false); addTransform(booleanType, defType, "Boolean", "valueOf", true, false); addTransform(booleanType, booleanobjType, "Boolean", "valueOf", true, false); @@ -539,12 +539,6 @@ public final class Definition { addTransform(byteType, defType, "Byte", "valueOf", true, false); addTransform(byteType, numberType, "Byte", "valueOf", true, false); addTransform(byteType, byteobjType, "Byte", "valueOf", true, false); - addTransform(byteType, shortobjType, "Utility", "byteToShort", true, false); - addTransform(byteType, charobjType, "Utility", "byteToCharacter", true, true); - addTransform(byteType, intobjType, "Utility", "byteToInteger", true, false); - addTransform(byteType, longobjType, "Utility", "byteToLong", true, false); - addTransform(byteType, floatobjType, "Utility", "byteToFloat", true, false); - addTransform(byteType, doubleobjType, "Utility", "byteToDouble", true, false); addTransform(shortType, byteType, true); addTransform(shortType, charType, true); @@ -555,13 +549,7 @@ public final class Definition { addTransform(shortType, objectType, "Short", "valueOf", true, false); addTransform(shortType, defType, "Short", "valueOf", true, false); addTransform(shortType, numberType, "Short", "valueOf", true, false); - addTransform(shortType, byteobjType, "Utility", "shortToByte", true, true); addTransform(shortType, shortobjType, "Short", "valueOf", true, false); - addTransform(shortType, charobjType, "Utility", "shortToCharacter", true, true); - addTransform(shortType, intobjType, "Utility", "shortToInteger", true, false); - addTransform(shortType, longobjType, "Utility", "shortToLong", true, false); - addTransform(shortType, floatobjType, "Utility", "shortToFloat", true, false); - addTransform(shortType, doubleobjType, "Utility", "shortToDouble", true, false); addTransform(charType, byteType, true); addTransform(charType, shortType, true); @@ -572,13 +560,7 @@ public final class Definition { addTransform(charType, objectType, "Character", "valueOf", true, false); addTransform(charType, defType, "Character", "valueOf", true, false); addTransform(charType, numberType, "Utility", "charToInteger", true, false); - addTransform(charType, byteobjType, "Utility", "charToByte", true, true); - addTransform(charType, shortobjType, "Utility", "charToShort", true, true); addTransform(charType, charobjType, "Character", "valueOf", true, false); - addTransform(charType, intobjType, "Utility", "charToInteger", true, false); - addTransform(charType, longobjType, "Utility", "charToLong", true, false); - addTransform(charType, floatobjType, "Utility", "charToFloat", true, false); - addTransform(charType, doubleobjType, "Utility", "charToDouble", true, false); addTransform(charType, stringType, "Utility", "charToString", true, true); addTransform(intType, byteType, true); @@ -590,13 +572,7 @@ public final class Definition { addTransform(intType, objectType, "Integer", "valueOf", true, false); addTransform(intType, defType, "Integer", "valueOf", true, false); addTransform(intType, numberType, "Integer", "valueOf", true, false); - addTransform(intType, byteobjType, "Utility", "intToByte", true, true); - addTransform(intType, shortobjType, "Utility", "intToShort", true, true); - addTransform(intType, charobjType, "Utility", "intToCharacter", true, true); addTransform(intType, intobjType, "Integer", "valueOf", true, false); - addTransform(intType, longobjType, "Utility", "intToLong", true, false); - addTransform(intType, floatobjType, "Utility", "intToFloat", true, false); - addTransform(intType, doubleobjType, "Utility", "intToDouble", true, false); addTransform(longType, byteType, true); addTransform(longType, shortType, true); @@ -607,13 +583,7 @@ public final class Definition { addTransform(longType, objectType, "Long", "valueOf", true, false); addTransform(longType, defType, "Long", "valueOf", true, false); addTransform(longType, numberType, "Long", "valueOf", true, false); - addTransform(longType, byteobjType, "Utility", "longToByte", true, true); - addTransform(longType, shortobjType, "Utility", "longToShort", true, true); - addTransform(longType, charobjType, "Utility", "longToCharacter", true, true); - addTransform(longType, intobjType, "Utility", "longToInteger", true, true); addTransform(longType, longobjType, "Long", "valueOf", true, false); - addTransform(longType, floatobjType, "Utility", "longToFloat", true, false); - addTransform(longType, doubleobjType, "Utility", "longToDouble", true, false); addTransform(floatType, byteType, true); addTransform(floatType, shortType, true); @@ -624,13 +594,7 @@ public final class Definition { addTransform(floatType, objectType, "Float", "valueOf", true, false); addTransform(floatType, defType, "Float", "valueOf", true, false); addTransform(floatType, numberType, "Float", "valueOf", true, false); - addTransform(floatType, byteobjType, "Utility", "floatToByte", true, true); - addTransform(floatType, shortobjType, "Utility", "floatToShort", true, true); - addTransform(floatType, charobjType, "Utility", "floatToCharacter", true, true); - addTransform(floatType, intobjType, "Utility", "floatToInteger", true, true); - addTransform(floatType, longobjType, "Utility", "floatToLong", true, true); addTransform(floatType, floatobjType, "Float", "valueOf", true, false); - addTransform(floatType, doubleobjType, "Utility", "floatToDouble", true, false); addTransform(doubleType, byteType, true); addTransform(doubleType, shortType, true); @@ -641,23 +605,8 @@ public final class Definition { addTransform(doubleType, objectType, "Double", "valueOf", true, false); addTransform(doubleType, defType, "Double", "valueOf", true, false); addTransform(doubleType, numberType, "Double", "valueOf", true, false); - addTransform(doubleType, byteobjType, "Utility", "doubleToByte", true, true); - addTransform(doubleType, shortobjType, "Utility", "doubleToShort", true, true); - addTransform(doubleType, charobjType, "Utility", "doubleToCharacter", true, true); - addTransform(doubleType, intobjType, "Utility", "doubleToInteger", true, true); - addTransform(doubleType, longobjType, "Utility", "doubleToLong", true, true); - addTransform(doubleType, floatobjType, "Utility", "doubleToFloat", true, true); addTransform(doubleType, doubleobjType, "Double", "valueOf", true, false); - addTransform(objectType, booleanType, "Boolean", "booleanValue", false, true); - addTransform(objectType, byteType, "Number", "byteValue", false, true); - addTransform(objectType, shortType, "Number", "shortValue", false, true); - addTransform(objectType, charType, "Character", "charValue", false, true); - addTransform(objectType, intType, "Number", "intValue", false, true); - addTransform(objectType, longType, "Number", "longValue", false, true); - addTransform(objectType, floatType, "Number", "floatValue", false, true); - addTransform(objectType, doubleType, "Number", "doubleValue", false, true); - addTransform(defType, booleanType, "Boolean", "booleanValue", false, false); addTransform(defType, byteType, "Def", "DefTobyteImplicit", true, false); addTransform(defType, shortType, "Def", "DefToshortImplicit", true, false); @@ -666,13 +615,6 @@ public final class Definition { addTransform(defType, longType, "Def", "DefTolongImplicit", true, false); addTransform(defType, floatType, "Def", "DefTofloatImplicit", true, false); addTransform(defType, doubleType, "Def", "DefTodoubleImplicit", true, false); - addTransform(defType, byteobjType, "Def", "DefToByteImplicit", true, false); - addTransform(defType, shortobjType, "Def", "DefToShortImplicit", true, false); - addTransform(defType, charobjType, "Def", "DefToCharacterImplicit", true, false); - addTransform(defType, intobjType, "Def", "DefToIntegerImplicit", true, false); - addTransform(defType, longobjType, "Def", "DefToLongImplicit", true, false); - addTransform(defType, floatobjType, "Def", "DefToFloatImplicit", true, false); - addTransform(defType, doubleobjType, "Def", "DefToDoubleImplicit", true, false); addTransform(defType, byteType, "Def", "DefTobyteExplicit", true, true); addTransform(defType, shortType, "Def", "DefToshortExplicit", true, true); addTransform(defType, charType, "Def", "DefTocharExplicit", true, true); @@ -680,130 +622,6 @@ public final class Definition { addTransform(defType, longType, "Def", "DefTolongExplicit", true, true); addTransform(defType, floatType, "Def", "DefTofloatExplicit", true, true); addTransform(defType, doubleType, "Def", "DefTodoubleExplicit", true, true); - addTransform(defType, byteobjType, "Def", "DefToByteExplicit", true, true); - addTransform(defType, shortobjType, "Def", "DefToShortExplicit", true, true); - addTransform(defType, charobjType, "Def", "DefToCharacterExplicit", true, true); - addTransform(defType, intobjType, "Def", "DefToIntegerExplicit", true, true); - addTransform(defType, longobjType, "Def", "DefToLongExplicit", true, true); - addTransform(defType, floatobjType, "Def", "DefToFloatExplicit", true, true); - addTransform(defType, doubleobjType, "Def", "DefToDoubleExplicit", true, true); - - addTransform(numberType, byteType, "Number", "byteValue", false, true); - addTransform(numberType, shortType, "Number", "shortValue", false, true); - addTransform(numberType, charType, "Utility", "NumberTochar", true, true); - addTransform(numberType, intType, "Number", "intValue", false, true); - addTransform(numberType, longType, "Number", "longValue", false, true); - addTransform(numberType, floatType, "Number", "floatValue", false, true); - addTransform(numberType, doubleType, "Number", "doubleValue", false, true); - addTransform(numberType, booleanobjType, "Utility", "NumberToBoolean", true, true); - addTransform(numberType, byteobjType, "Utility", "NumberToByte", true, true); - addTransform(numberType, shortobjType, "Utility", "NumberToShort", true, true); - addTransform(numberType, charobjType, "Utility", "NumberToCharacter", true, true); - addTransform(numberType, intobjType, "Utility", "NumberToInteger", true, true); - addTransform(numberType, longobjType, "Utility", "NumberToLong", true, true); - addTransform(numberType, floatobjType, "Utility", "NumberToFloat", true, true); - addTransform(numberType, doubleobjType, "Utility", "NumberToDouble", true, true); - - addTransform(booleanobjType, booleanType, "Boolean", "booleanValue", false, false); - - addTransform(byteobjType, byteType, "Byte", "byteValue", false, false); - addTransform(byteobjType, shortType, "Byte", "shortValue", false, false); - addTransform(byteobjType, charType, "Utility", "ByteTochar", true, false); - addTransform(byteobjType, intType, "Byte", "intValue", false, false); - addTransform(byteobjType, longType, "Byte", "longValue", false, false); - addTransform(byteobjType, floatType, "Byte", "floatValue", false, false); - addTransform(byteobjType, doubleType, "Byte", "doubleValue", false, false); - addTransform(byteobjType, shortobjType, "Utility", "NumberToShort", true, false); - addTransform(byteobjType, charobjType, "Utility", "NumberToCharacter", true, false); - addTransform(byteobjType, intobjType, "Utility", "NumberToInteger", true, false); - addTransform(byteobjType, longobjType, "Utility", "NumberToLong", true, false); - addTransform(byteobjType, floatobjType, "Utility", "NumberToFloat", true, false); - addTransform(byteobjType, doubleobjType, "Utility", "NumberToDouble", true, false); - - addTransform(shortobjType, byteType, "Short", "byteValue", false, true); - addTransform(shortobjType, shortType, "Short", "shortValue", false, true); - addTransform(shortobjType, charType, "Utility", "ShortTochar", true, false); - addTransform(shortobjType, intType, "Short", "intValue", false, false); - addTransform(shortobjType, longType, "Short", "longValue", false, false); - addTransform(shortobjType, floatType, "Short", "floatValue", false, false); - addTransform(shortobjType, doubleType, "Short", "doubleValue", false, false); - addTransform(shortobjType, byteobjType, "Utility", "NumberToByte", true, true); - addTransform(shortobjType, charobjType, "Utility", "NumberToCharacter", true, true); - addTransform(shortobjType, intobjType, "Utility", "NumberToInteger", true, false); - addTransform(shortobjType, longobjType, "Utility", "NumberToLong", true, false); - addTransform(shortobjType, floatobjType, "Utility", "NumberToFloat", true, false); - addTransform(shortobjType, doubleobjType, "Utility", "NumberToDouble", true, false); - - addTransform(charobjType, byteType, "Utility", "CharacterTobyte", true, true); - addTransform(charobjType, shortType, "Utility", "CharacterToshort", true, false); - addTransform(charobjType, charType, "Character", "charValue", false, true); - addTransform(charobjType, intType, "Utility", "CharacterToint", true, false); - addTransform(charobjType, longType, "Utility", "CharacterTolong", true, false); - addTransform(charobjType, floatType, "Utility", "CharacterTofloat", true, false); - addTransform(charobjType, doubleType, "Utility", "CharacterTodouble", true, false); - addTransform(charobjType, byteobjType, "Utility", "CharacterToByte", true, true); - addTransform(charobjType, shortobjType, "Utility", "CharacterToShort", true, true); - addTransform(charobjType, intobjType, "Utility", "CharacterToInteger", true, false); - addTransform(charobjType, longobjType, "Utility", "CharacterToLong", true, false); - addTransform(charobjType, floatobjType, "Utility", "CharacterToFloat", true, false); - addTransform(charobjType, doubleobjType, "Utility", "CharacterToDouble", true, false); - addTransform(charobjType, stringType, "Utility", "CharacterToString", true, true); - - addTransform(intobjType, byteType, "Integer", "byteValue", false, true); - addTransform(intobjType, shortType, "Integer", "shortValue", false, true); - addTransform(intobjType, charType, "Utility", "IntegerTochar", true, true); - addTransform(intobjType, intType, "Integer", "intValue", false, false); - addTransform(intobjType, longType, "Integer", "longValue", false, false); - addTransform(intobjType, floatType, "Integer", "floatValue", false, false); - addTransform(intobjType, doubleType, "Integer", "doubleValue", false, false); - addTransform(intobjType, byteobjType, "Utility", "NumberToByte", true, true); - addTransform(intobjType, shortobjType, "Utility", "NumberToShort", true, true); - addTransform(intobjType, charobjType, "Utility", "NumberToCharacter", true, true); - addTransform(intobjType, longobjType, "Utility", "NumberToLong", true, false); - addTransform(intobjType, floatobjType, "Utility", "NumberToFloat", true, false); - addTransform(intobjType, doubleobjType, "Utility", "NumberToDouble", true, false); - - addTransform(longobjType, byteType, "Long", "byteValue", false, true); - addTransform(longobjType, shortType, "Long", "shortValue", false, true); - addTransform(longobjType, charType, "Utility", "LongTochar", true, true); - addTransform(longobjType, intType, "Long", "intValue", false, true); - addTransform(longobjType, longType, "Long", "longValue", false, false); - addTransform(longobjType, floatType, "Long", "floatValue", false, false); - addTransform(longobjType, doubleType, "Long", "doubleValue", false, false); - addTransform(longobjType, byteobjType, "Utility", "NumberToByte", true, true); - addTransform(longobjType, shortobjType, "Utility", "NumberToShort", true, true); - addTransform(longobjType, charobjType, "Utility", "NumberToCharacter", true, true); - addTransform(longobjType, intobjType, "Utility", "NumberToInteger", true, true); - addTransform(longobjType, floatobjType, "Utility", "NumberToFloat", true, false); - addTransform(longobjType, doubleobjType, "Utility", "NumberToDouble", true, false); - - addTransform(floatobjType, byteType, "Float", "byteValue", false, true); - addTransform(floatobjType, shortType, "Float", "shortValue", false, true); - addTransform(floatobjType, charType, "Utility", "FloatTochar", true, true); - addTransform(floatobjType, intType, "Float", "intValue", false, true); - addTransform(floatobjType, longType, "Float", "longValue", false, true); - addTransform(floatobjType, floatType, "Float", "floatValue", false, false); - addTransform(floatobjType, doubleType, "Float", "doubleValue", false, false); - addTransform(floatobjType, byteobjType, "Utility", "NumberToByte", true, true); - addTransform(floatobjType, shortobjType, "Utility", "NumberToShort", true, true); - addTransform(floatobjType, charobjType, "Utility", "NumberToCharacter", true, true); - addTransform(floatobjType, intobjType, "Utility", "NumberToInteger", true, true); - addTransform(floatobjType, longobjType, "Utility", "NumberToLong", true, true); - addTransform(floatobjType, doubleobjType, "Utility", "NumberToDouble", true, false); - - addTransform(doubleobjType, byteType, "Double", "byteValue", false, true); - addTransform(doubleobjType, shortType, "Double", "shortValue", false, true); - addTransform(doubleobjType, charType, "Utility", "DoubleTochar", true, true); - addTransform(doubleobjType, intType, "Double", "intValue", false, true); - addTransform(doubleobjType, longType, "Double", "longValue", false, true); - addTransform(doubleobjType, floatType, "Double", "floatValue", false, true); - addTransform(doubleobjType, doubleType, "Double", "doubleValue", false, false); - addTransform(doubleobjType, byteobjType, "Utility", "NumberToByte", true, true); - addTransform(doubleobjType, shortobjType, "Utility", "NumberToShort", true, true); - addTransform(doubleobjType, charobjType, "Utility", "NumberToCharacter", true, true); - addTransform(doubleobjType, intobjType, "Utility", "NumberToInteger", true, true); - addTransform(doubleobjType, longobjType, "Utility", "NumberToLong", true, true); - addTransform(doubleobjType, floatobjType, "Utility", "NumberToFloat", true, true); addTransform(stringType, charType, "Utility", "StringTochar", true, true); addTransform(stringType, charobjType, "Utility", "StringToCharacter", true, true); @@ -823,7 +641,7 @@ public final class Definition { structsMap.put(name, struct); simpleTypesMap.put(name, getType(name)); } - + private final void addConstructorInternal(final String struct, final String name, final Type[] args) { final Struct owner = structsMap.get(struct); @@ -874,8 +692,8 @@ public final class Definition { owner.constructors.put(methodKey, constructor); } - - /** + + /** * Adds a new signature to the definition. *

* Signatures have the following forms: @@ -930,7 +748,7 @@ public final class Definition { } } - private final void addMethodInternal(final String struct, final String name, final String alias, + private final void addMethodInternal(final String struct, final String name, final String alias, final Type rtn, final Type[] args) { final Struct owner = structsMap.get(struct); @@ -968,7 +786,7 @@ public final class Definition { try { reflect = owner.clazz.getMethod(alias == null ? name : alias, classes); } catch (final NoSuchMethodException exception) { - throw new IllegalArgumentException("Method [" + (alias == null ? name : alias) + + throw new IllegalArgumentException("Method [" + (alias == null ? name : alias) + "] not found for class [" + owner.clazz.getName() + "]" + " with arguments " + Arrays.toString(classes) + "."); } @@ -1001,7 +819,7 @@ public final class Definition { owner.methods.put(methodKey, method); } } - + private final void addFieldInternal(final String struct, final String name, final String alias, final Type type) { final Struct owner = structsMap.get(struct); @@ -1029,7 +847,7 @@ public final class Definition { throw new IllegalArgumentException("Field [" + (alias == null ? name : alias) + "]" + " not found for class [" + owner.clazz.getName() + "]."); } - + final int modifiers = reflect.getModifiers(); boolean isStatic = java.lang.reflect.Modifier.isStatic(modifiers); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java index f22b7394ca0..483e82cc500 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java @@ -80,7 +80,7 @@ public final class EBinary extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true); if (promote == null) { throw new ClassCastException(error("Cannot apply multiply [*] to types " + @@ -116,7 +116,7 @@ public final class EBinary extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true); if (promote == null) { throw new ClassCastException(error("Cannot apply divide [/] to types " + @@ -152,7 +152,7 @@ public final class EBinary extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true); if (promote == null) { throw new ClassCastException(error("Cannot apply remainder [%] to types " + @@ -240,7 +240,7 @@ public final class EBinary extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true); if (promote == null) { throw new ClassCastException(error("Cannot apply subtract [-] to types " + @@ -276,7 +276,7 @@ public final class EBinary extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, false, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, false); if (promote == null) { throw new ClassCastException(error("Cannot apply left shift [<<] to types " + @@ -309,7 +309,7 @@ public final class EBinary extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, false, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, false); if (promote == null) { throw new ClassCastException(error("Cannot apply right shift [>>] to types " + @@ -342,7 +342,7 @@ public final class EBinary extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, false, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, false); if (promote == null) { throw new ClassCastException(error("Cannot apply unsigned shift [>>>] to types " + @@ -375,7 +375,7 @@ public final class EBinary extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, false, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, false); if (promote == null) { throw new ClassCastException(error("Cannot apply and [&] to types " + @@ -441,7 +441,7 @@ public final class EBinary extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, false, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, false); if (promote == null) { throw new ClassCastException(error("Cannot apply or [|] to types " + diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java index 933295f9beb..0b91ee406e8 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java @@ -159,21 +159,21 @@ public final class EChain extends AExpression { expression.analyze(settings, definition, variables); if (operation == Operation.MUL) { - promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true, true); + promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true); } else if (operation == Operation.DIV) { - promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true, true); + promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true); } else if (operation == Operation.REM) { - promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true, true); + promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true); } else if (operation == Operation.ADD) { promote = AnalyzerCaster.promoteAdd(definition, last.after, expression.actual); } else if (operation == Operation.SUB) { - promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true, true); + promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true); } else if (operation == Operation.LSH) { - promote = AnalyzerCaster.promoteNumeric(definition, last.after, false, true); + promote = AnalyzerCaster.promoteNumeric(definition, last.after, false); } else if (operation == Operation.RSH) { - promote = AnalyzerCaster.promoteNumeric(definition, last.after, false, true); + promote = AnalyzerCaster.promoteNumeric(definition, last.after, false); } else if (operation == Operation.USH) { - promote = AnalyzerCaster.promoteNumeric(definition, last.after, false, true); + promote = AnalyzerCaster.promoteNumeric(definition, last.after, false); } else if (operation == Operation.BWAND) { promote = AnalyzerCaster.promoteXor(definition, last.after, expression.actual); } else if (operation == Operation.XOR) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java index a65e82e02fa..270f95e0a92 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java @@ -126,7 +126,7 @@ public final class EComp extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteReference(definition, left.actual, right.actual); + final Type promote = AnalyzerCaster.promoteEquality(definition, left.actual, right.actual); if (promote == null) { throw new ClassCastException(error("Cannot apply reference equals [===] to types " + @@ -214,7 +214,7 @@ public final class EComp extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteReference(definition, left.actual, right.actual); + final Type promote = AnalyzerCaster.promoteEquality(definition, left.actual, right.actual); if (promote == null) { throw new ClassCastException(error("Cannot apply reference not equals [!==] to types " + @@ -256,7 +256,7 @@ public final class EComp extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true); if (promote == null) { throw new ClassCastException(error("Cannot apply greater than or equals [>=] to types " + @@ -292,7 +292,7 @@ public final class EComp extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true); if (promote == null) { throw new ClassCastException(error("Cannot apply greater than [>] to types " + @@ -328,7 +328,7 @@ public final class EComp extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true); if (promote == null) { throw new ClassCastException(error("Cannot apply less than or equals [<=] to types " + @@ -364,7 +364,7 @@ public final class EComp extends AExpression { left.analyze(settings, definition, variables); right.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true); if (promote == null) { throw new ClassCastException(error("Cannot apply less than [>=] to types " + diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java index 7e52790fa50..3e34c16ab97 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java @@ -77,7 +77,7 @@ public final class EUnary extends AExpression { void analyzeBWNot(final CompilerSettings settings, final Definition definition, final Variables variables) { child.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, child.actual, false, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, child.actual, false); if (promote == null) { throw new ClassCastException(error("Cannot apply not [~] to type [" + child.actual.name + "].")); @@ -104,7 +104,7 @@ public final class EUnary extends AExpression { void analyzerAdd(final CompilerSettings settings, final Definition definition, final Variables variables) { child.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, child.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, child.actual, true); if (promote == null) { throw new ClassCastException(error("Cannot apply positive [+] to type [" + child.actual.name + "].")); @@ -135,7 +135,7 @@ public final class EUnary extends AExpression { void analyzerSub(final CompilerSettings settings, final Definition definition, final Variables variables) { child.analyze(settings, definition, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, child.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(definition, child.actual, true); if (promote == null) { throw new ClassCastException(error("Cannot apply negative [-] to type [" + child.actual.name + "].")); diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefOperationTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefOperationTests.java index bfc0d142045..9ae657f7c1b 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefOperationTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefOperationTests.java @@ -22,10 +22,10 @@ package org.elasticsearch.painless; public class DefOperationTests extends ScriptTestCase { public void testIllegalCast() { Exception exception = expectThrows(ClassCastException.class, () -> exec("def x = 1.0; int y = x; return y;")); - assertTrue(exception.getMessage().contains("java.lang.Double cannot be cast to java.lang.Integer")); + assertTrue(exception.getMessage().contains("java.lang.double cannot be cast to java.lang.int")); exception = expectThrows(ClassCastException.class, () -> exec("def x = (short)1; byte y = x; return y;")); - assertTrue(exception.getMessage().contains("java.lang.Short cannot be cast to java.lang.Byte")); + assertTrue(exception.getMessage().contains("java.lang.short cannot be cast to java.lang.byte")); } public void testNot() { @@ -103,13 +103,13 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(4D, exec("def x = (float)2; def y = (double)2; return x * y")); assertEquals(4D, exec("def x = (double)2; def y = (double)2; return x * y")); - assertEquals(4, exec("def x = (Byte)2; def y = (byte)2; return x * y")); - assertEquals(4, exec("def x = (Short)2; def y = (short)2; return x * y")); - assertEquals(4, exec("def x = (Character)2; def y = (char)2; return x * y")); - assertEquals(4, exec("def x = (Integer)2; def y = (int)2; return x * y")); - assertEquals(4L, exec("def x = (Long)2; def y = (long)2; return x * y")); - assertEquals(4F, exec("def x = (Float)2; def y = (float)2; return x * y")); - assertEquals(4D, exec("def x = (Double)2; def y = (double)2; return x * y")); + assertEquals(4, exec("def x = (byte)2; def y = (byte)2; return x * y")); + assertEquals(4, exec("def x = (short)2; def y = (short)2; return x * y")); + assertEquals(4, exec("def x = (char)2; def y = (char)2; return x * y")); + assertEquals(4, exec("def x = (int)2; def y = (int)2; return x * y")); + assertEquals(4L, exec("def x = (long)2; def y = (long)2; return x * y")); + assertEquals(4F, exec("def x = (float)2; def y = (float)2; return x * y")); + assertEquals(4D, exec("def x = (double)2; def y = (double)2; return x * y")); } public void testDiv() { @@ -169,13 +169,13 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(1D, exec("def x = (float)2; def y = (double)2; return x / y")); assertEquals(1D, exec("def x = (double)2; def y = (double)2; return x / y")); - assertEquals(1, exec("def x = (Byte)2; def y = (byte)2; return x / y")); - assertEquals(1, exec("def x = (Short)2; def y = (short)2; return x / y")); - assertEquals(1, exec("def x = (Character)2; def y = (char)2; return x / y")); - assertEquals(1, exec("def x = (Integer)2; def y = (int)2; return x / y")); - assertEquals(1L, exec("def x = (Long)2; def y = (long)2; return x / y")); - assertEquals(1F, exec("def x = (Float)2; def y = (float)2; return x / y")); - assertEquals(1D, exec("def x = (Double)2; def y = (double)2; return x / y")); + assertEquals(1, exec("def x = (byte)2; def y = (byte)2; return x / y")); + assertEquals(1, exec("def x = (short)2; def y = (short)2; return x / y")); + assertEquals(1, exec("def x = (char)2; def y = (char)2; return x / y")); + assertEquals(1, exec("def x = (int)2; def y = (int)2; return x / y")); + assertEquals(1L, exec("def x = (long)2; def y = (long)2; return x / y")); + assertEquals(1F, exec("def x = (float)2; def y = (float)2; return x / y")); + assertEquals(1D, exec("def x = (double)2; def y = (double)2; return x / y")); } public void testRem() { @@ -235,13 +235,13 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(0D, exec("def x = (float)2; def y = (double)2; return x % y")); assertEquals(0D, exec("def x = (double)2; def y = (double)2; return x % y")); - assertEquals(0, exec("def x = (Byte)2; def y = (byte)2; return x % y")); - assertEquals(0, exec("def x = (Short)2; def y = (short)2; return x % y")); - assertEquals(0, exec("def x = (Character)2; def y = (char)2; return x % y")); - assertEquals(0, exec("def x = (Integer)2; def y = (int)2; return x % y")); - assertEquals(0L, exec("def x = (Long)2; def y = (long)2; return x % y")); - assertEquals(0F, exec("def x = (Float)2; def y = (float)2; return x % y")); - assertEquals(0D, exec("def x = (Double)2; def y = (double)2; return x % y")); + assertEquals(0, exec("def x = (byte)2; def y = (byte)2; return x % y")); + assertEquals(0, exec("def x = (short)2; def y = (short)2; return x % y")); + assertEquals(0, exec("def x = (char)2; def y = (char)2; return x % y")); + assertEquals(0, exec("def x = (int)2; def y = (int)2; return x % y")); + assertEquals(0L, exec("def x = (long)2; def y = (long)2; return x % y")); + assertEquals(0F, exec("def x = (float)2; def y = (float)2; return x % y")); + assertEquals(0D, exec("def x = (double)2; def y = (double)2; return x % y")); } public void testAdd() { @@ -301,13 +301,13 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(2D, exec("def x = (float)1; def y = (double)1; return x + y")); assertEquals(2D, exec("def x = (double)1; def y = (double)1; return x + y")); - assertEquals(2, exec("def x = (Byte)1; def y = (byte)1; return x + y")); - assertEquals(2, exec("def x = (Short)1; def y = (short)1; return x + y")); - assertEquals(2, exec("def x = (Character)1; def y = (char)1; return x + y")); - assertEquals(2, exec("def x = (Integer)1; def y = (int)1; return x + y")); - assertEquals(2L, exec("def x = (Long)1; def y = (long)1; return x + y")); - assertEquals(2F, exec("def x = (Float)1; def y = (float)1; return x + y")); - assertEquals(2D, exec("def x = (Double)1; def y = (double)1; return x + y")); + assertEquals(2, exec("def x = (byte)1; def y = (byte)1; return x + y")); + assertEquals(2, exec("def x = (short)1; def y = (short)1; return x + y")); + assertEquals(2, exec("def x = (char)1; def y = (char)1; return x + y")); + assertEquals(2, exec("def x = (int)1; def y = (int)1; return x + y")); + assertEquals(2L, exec("def x = (long)1; def y = (long)1; return x + y")); + assertEquals(2F, exec("def x = (float)1; def y = (float)1; return x + y")); + assertEquals(2D, exec("def x = (double)1; def y = (double)1; return x + y")); } public void testSub() { @@ -367,13 +367,13 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(0D, exec("def x = (float)1; def y = (double)1; return x - y")); assertEquals(0D, exec("def x = (double)1; def y = (double)1; return x - y")); - assertEquals(0, exec("def x = (Byte)1; def y = (byte)1; return x - y")); - assertEquals(0, exec("def x = (Short)1; def y = (short)1; return x - y")); - assertEquals(0, exec("def x = (Character)1; def y = (char)1; return x - y")); - assertEquals(0, exec("def x = (Integer)1; def y = (int)1; return x - y")); - assertEquals(0L, exec("def x = (Long)1; def y = (long)1; return x - y")); - assertEquals(0F, exec("def x = (Float)1; def y = (float)1; return x - y")); - assertEquals(0D, exec("def x = (Double)1; def y = (double)1; return x - y")); + assertEquals(0, exec("def x = (byte)1; def y = (byte)1; return x - y")); + assertEquals(0, exec("def x = (short)1; def y = (short)1; return x - y")); + assertEquals(0, exec("def x = (char)1; def y = (char)1; return x - y")); + assertEquals(0, exec("def x = (int)1; def y = (int)1; return x - y")); + assertEquals(0L, exec("def x = (long)1; def y = (long)1; return x - y")); + assertEquals(0F, exec("def x = (float)1; def y = (float)1; return x - y")); + assertEquals(0D, exec("def x = (double)1; def y = (double)1; return x - y")); } public void testLsh() { @@ -433,13 +433,13 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(2L, exec("def x = (float)1; def y = (double)1; return x << y")); assertEquals(2L, exec("def x = (double)1; def y = (double)1; return x << y")); - assertEquals(2, exec("def x = (Byte)1; def y = (byte)1; return x << y")); - assertEquals(2, exec("def x = (Short)1; def y = (short)1; return x << y")); - assertEquals(2, exec("def x = (Character)1; def y = (char)1; return x << y")); - assertEquals(2, exec("def x = (Integer)1; def y = (int)1; return x << y")); - assertEquals(2L, exec("def x = (Long)1; def y = (long)1; return x << y")); - assertEquals(2L, exec("def x = (Float)1; def y = (float)1; return x << y")); - assertEquals(2L, exec("def x = (Double)1; def y = (double)1; return x << y")); + assertEquals(2, exec("def x = (byte)1; def y = (byte)1; return x << y")); + assertEquals(2, exec("def x = (short)1; def y = (short)1; return x << y")); + assertEquals(2, exec("def x = (char)1; def y = (char)1; return x << y")); + assertEquals(2, exec("def x = (int)1; def y = (int)1; return x << y")); + assertEquals(2L, exec("def x = (long)1; def y = (long)1; return x << y")); + assertEquals(2L, exec("def x = (float)1; def y = (float)1; return x << y")); + assertEquals(2L, exec("def x = (double)1; def y = (double)1; return x << y")); } public void testRsh() { @@ -499,13 +499,13 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(2L, exec("def x = (float)4; def y = (double)1; return x >> y")); assertEquals(2L, exec("def x = (double)4; def y = (double)1; return x >> y")); - assertEquals(2, exec("def x = (Byte)4; def y = (byte)1; return x >> y")); - assertEquals(2, exec("def x = (Short)4; def y = (short)1; return x >> y")); - assertEquals(2, exec("def x = (Character)4; def y = (char)1; return x >> y")); - assertEquals(2, exec("def x = (Integer)4; def y = (int)1; return x >> y")); - assertEquals(2L, exec("def x = (Long)4; def y = (long)1; return x >> y")); - assertEquals(2L, exec("def x = (Float)4; def y = (float)1; return x >> y")); - assertEquals(2L, exec("def x = (Double)4; def y = (double)1; return x >> y")); + assertEquals(2, exec("def x = (byte)4; def y = (byte)1; return x >> y")); + assertEquals(2, exec("def x = (short)4; def y = (short)1; return x >> y")); + assertEquals(2, exec("def x = (char)4; def y = (char)1; return x >> y")); + assertEquals(2, exec("def x = (int)4; def y = (int)1; return x >> y")); + assertEquals(2L, exec("def x = (long)4; def y = (long)1; return x >> y")); + assertEquals(2L, exec("def x = (float)4; def y = (float)1; return x >> y")); + assertEquals(2L, exec("def x = (double)4; def y = (double)1; return x >> y")); } public void testUsh() { @@ -565,13 +565,13 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(2L, exec("def x = (float)4; def y = (double)1; return x >>> y")); assertEquals(2L, exec("def x = (double)4; def y = (double)1; return x >>> y")); - assertEquals(2, exec("def x = (Byte)4; def y = (byte)1; return x >>> y")); - assertEquals(2, exec("def x = (Short)4; def y = (short)1; return x >>> y")); - assertEquals(2, exec("def x = (Character)4; def y = (char)1; return x >>> y")); - assertEquals(2, exec("def x = (Integer)4; def y = (int)1; return x >>> y")); - assertEquals(2L, exec("def x = (Long)4; def y = (long)1; return x >>> y")); - assertEquals(2L, exec("def x = (Float)4; def y = (float)1; return x >>> y")); - assertEquals(2L, exec("def x = (Double)4; def y = (double)1; return x >>> y")); + assertEquals(2, exec("def x = (byte)4; def y = (byte)1; return x >>> y")); + assertEquals(2, exec("def x = (short)4; def y = (short)1; return x >>> y")); + assertEquals(2, exec("def x = (char)4; def y = (char)1; return x >>> y")); + assertEquals(2, exec("def x = (int)4; def y = (int)1; return x >>> y")); + assertEquals(2L, exec("def x = (long)4; def y = (long)1; return x >>> y")); + assertEquals(2L, exec("def x = (float)4; def y = (float)1; return x >>> y")); + assertEquals(2L, exec("def x = (double)4; def y = (double)1; return x >>> y")); } public void testAnd() { @@ -631,13 +631,13 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(0L, exec("def x = (float)4; def y = (double)1; return x & y")); assertEquals(0L, exec("def x = (double)4; def y = (double)1; return x & y")); - assertEquals(0, exec("def x = (Byte)4; def y = (byte)1; return x & y")); - assertEquals(0, exec("def x = (Short)4; def y = (short)1; return x & y")); - assertEquals(0, exec("def x = (Character)4; def y = (char)1; return x & y")); - assertEquals(0, exec("def x = (Integer)4; def y = (int)1; return x & y")); - assertEquals(0L, exec("def x = (Long)4; def y = (long)1; return x & y")); - assertEquals(0L, exec("def x = (Float)4; def y = (float)1; return x & y")); - assertEquals(0L, exec("def x = (Double)4; def y = (double)1; return x & y")); + assertEquals(0, exec("def x = (byte)4; def y = (byte)1; return x & y")); + assertEquals(0, exec("def x = (short)4; def y = (short)1; return x & y")); + assertEquals(0, exec("def x = (char)4; def y = (char)1; return x & y")); + assertEquals(0, exec("def x = (int)4; def y = (int)1; return x & y")); + assertEquals(0L, exec("def x = (long)4; def y = (long)1; return x & y")); + assertEquals(0L, exec("def x = (float)4; def y = (float)1; return x & y")); + assertEquals(0L, exec("def x = (double)4; def y = (double)1; return x & y")); } public void testXor() { @@ -697,13 +697,13 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(5L, exec("def x = (float)4; def y = (double)1; return x ^ y")); assertEquals(5L, exec("def x = (double)4; def y = (double)1; return x ^ y")); - assertEquals(5, exec("def x = (Byte)4; def y = (byte)1; return x ^ y")); - assertEquals(5, exec("def x = (Short)4; def y = (short)1; return x ^ y")); - assertEquals(5, exec("def x = (Character)4; def y = (char)1; return x ^ y")); - assertEquals(5, exec("def x = (Integer)4; def y = (int)1; return x ^ y")); - assertEquals(5L, exec("def x = (Long)4; def y = (long)1; return x ^ y")); - assertEquals(5L, exec("def x = (Float)4; def y = (float)1; return x ^ y")); - assertEquals(5L, exec("def x = (Double)4; def y = (double)1; return x ^ y")); + assertEquals(5, exec("def x = (byte)4; def y = (byte)1; return x ^ y")); + assertEquals(5, exec("def x = (short)4; def y = (short)1; return x ^ y")); + 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(5L, exec("def x = (float)4; def y = (float)1; return x ^ y")); + assertEquals(5L, exec("def x = (double)4; def y = (double)1; return x ^ y")); } public void testOr() { @@ -763,13 +763,13 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(5L, exec("def x = (float)4; def y = (double)1; return x | y")); assertEquals(5L, exec("def x = (double)4; def y = (double)1; return x | y")); - assertEquals(5, exec("def x = (Byte)4; def y = (byte)1; return x | y")); - assertEquals(5, exec("def x = (Short)4; def y = (short)1; return x | y")); - assertEquals(5, exec("def x = (Character)4; def y = (char)1; return x | y")); - assertEquals(5, exec("def x = (Integer)4; def y = (int)1; return x | y")); - assertEquals(5L, exec("def x = (Long)4; def y = (long)1; return x | y")); - assertEquals(5L, exec("def x = (Float)4; def y = (float)1; return x | y")); - assertEquals(5L, exec("def x = (Double)4; def y = (double)1; return x | y")); + assertEquals(5, exec("def x = (byte)4; def y = (byte)1; return x | y")); + assertEquals(5, exec("def x = (short)4; def y = (short)1; return x | y")); + 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(5L, exec("def x = (float)4; def y = (float)1; return x | y")); + assertEquals(5L, exec("def x = (double)4; def y = (double)1; return x | y")); } public void testEq() { From 64e2ef58078eb9066eff76656cffaa2e0db91b44 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Thu, 19 May 2016 23:38:14 -0700 Subject: [PATCH 08/22] Removed transforms. No user-facing boxing. --- .../painless/AnalyzerCaster.java | 711 ++++++++++++++++-- .../java/org/elasticsearch/painless/Def.java | 147 +--- .../elasticsearch/painless/Definition.java | 311 +------- .../elasticsearch/painless/MethodWriter.java | 139 ++-- .../org/elasticsearch/painless/Utility.java | 12 - .../painless/WriterConstants.java | 53 +- .../painless/node/AExpression.java | 8 +- .../elasticsearch/painless/node/EBinary.java | 2 +- .../elasticsearch/painless/node/EChain.java | 6 +- .../painless/node/EConditional.java | 2 + .../elasticsearch/painless/node/LCall.java | 3 +- .../elasticsearch/painless/node/LCast.java | 2 +- .../elasticsearch/painless/node/LDefCall.java | 1 + .../elasticsearch/painless/node/LNewObj.java | 1 + .../painless/node/SExpression.java | 1 + .../elasticsearch/painless/node/SReturn.java | 1 + .../painless/node/package-info.java | 1 + .../org/elasticsearch/painless/definition.txt | 154 ---- .../painless/BasicExpressionTests.java | 6 +- .../painless/CompoundAssignmentTests.java | 48 +- .../painless/ConditionalTests.java | 3 - .../elasticsearch/painless/EqualsTests.java | 12 +- .../elasticsearch/painless/StringTests.java | 44 +- 23 files changed, 852 insertions(+), 816 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java index 398dc0a7a61..11a334eff1d 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java @@ -20,98 +20,677 @@ package org.elasticsearch.painless; import org.elasticsearch.painless.Definition.Cast; -import org.elasticsearch.painless.Definition.Method; import org.elasticsearch.painless.Definition.Sort; -import org.elasticsearch.painless.Definition.Transform; import org.elasticsearch.painless.Definition.Type; -import java.lang.reflect.InvocationTargetException; - /** * 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(final Definition definition, - final String location, final Type actual, final Type expected, final boolean explicit) { - final Cast cast = new Cast(actual, expected, explicit); - + public static Cast getLegalCast(final Definition definition, final String location, final Type actual, + final Type expected, final boolean explicit, final boolean internal) { if (actual.equals(expected)) { return null; } - Cast transform = definition.transformsMap.get(cast); + switch (actual.sort) { + case BOOL: + switch (expected.sort) { + case DEF: + return new Cast(actual, definition.getType("def"), explicit, false, false, true, false); + case OBJECT: + case BOOL_OBJ: + if (internal) + return new Cast(actual, actual, explicit, false, false, false, true); + } - if (transform == null && explicit) { - transform = definition.transformsMap.get(new Cast(actual, expected, false)); - } + break; + case BYTE: + switch (expected.sort) { + case SHORT: + case INT: + case LONG: + case FLOAT: + case DOUBLE: + return new Cast(actual, expected, explicit); + case CHAR: + if (explicit) + return new Cast(actual, expected, true); - if (transform != null) { - return transform; + break; + case DEF: + return new Cast(actual, definition.getType("def"), explicit, false, false, true, false); + case OBJECT: + case NUMBER: + case BYTE_OBJ: + if (internal) + return new Cast(actual, actual, explicit, false, false, false, true); + + break; + case SHORT_OBJ: + if (internal) + return new Cast(actual, definition.getType("short"), explicit, false, false, false, true); + + break; + case INT_OBJ: + if (internal) + return new Cast(actual, definition.getType("int"), explicit, false, false, false, true); + + break; + case LONG_OBJ: + if (internal) + return new Cast(actual, definition.getType("long"), explicit, false, false, false, true); + + break; + case FLOAT_OBJ: + if (internal) + return new Cast(actual, definition.getType("float"), explicit, false, false, false, true); + + break; + case DOUBLE_OBJ: + if (internal) + return new Cast(actual, definition.getType("double"), explicit, false, false, false, true); + + break; + case CHAR_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("char"), explicit, false, false, false, true); + + break; + } + + break; + case SHORT: + switch (expected.sort) { + case INT: + case LONG: + case FLOAT: + case DOUBLE: + return new Cast(actual, expected, explicit); + case BYTE: + case CHAR: + if (explicit) + return new Cast(actual, expected, true); + + break; + case DEF: + return new Cast(actual, definition.getType("def"), explicit, false, false, true, false); + case OBJECT: + case NUMBER: + case SHORT_OBJ: + if (internal) + return new Cast(actual, actual, explicit, false, false, false, true); + + break; + case INT_OBJ: + if (internal) + return new Cast(actual, definition.getType("int"), explicit, false, false, false, true); + + break; + case LONG_OBJ: + if (internal) + return new Cast(actual, definition.getType("long"), explicit, false, false, false, true); + + break; + case FLOAT_OBJ: + if (internal) + return new Cast(actual, definition.getType("float"), explicit, false, false, false, true); + + break; + case DOUBLE_OBJ: + if (internal) + return new Cast(actual, definition.getType("double"), explicit, false, false, false, true); + + break; + case BYTE_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("byte"), true, false, false, false, true); + + break; + case CHAR_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("char"), true, false, false, false, true); + + break; + } + + break; + case CHAR: + switch (expected.sort) { + case INT: + case LONG: + case FLOAT: + case DOUBLE: + return new Cast(actual, expected, explicit); + case BYTE: + case SHORT: + if (explicit) + return new Cast(actual, expected, true); + + break; + case DEF: + return new Cast(actual, definition.getType("def"), explicit, false, false, true, false); + case OBJECT: + case NUMBER: + case CHAR_OBJ: + if (internal) + return new Cast(actual, actual, explicit, false, false, false, true); + + break; + case STRING: + return new Cast(actual, definition.getType("String"), explicit, false, false, false, false); + case INT_OBJ: + if (internal) + return new Cast(actual, definition.getType("int"), explicit, false, false, false, true); + + break; + case LONG_OBJ: + if (internal) + return new Cast(actual, definition.getType("long"), explicit, false, false, false, true); + + break; + case FLOAT_OBJ: + if (internal) + return new Cast(actual, definition.getType("float"), explicit, false, false, false, true); + + break; + case DOUBLE_OBJ: + if (internal) + return new Cast(actual, definition.getType("double"), explicit, false, false, false, true); + + break; + case BYTE_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("byte"), true, false, false, false, true); + + break; + case SHORT_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("short"), true, false, false, false, true); + + break; + } + + break; + case INT: + switch (expected.sort) { + case LONG: + case FLOAT: + case DOUBLE: + return new Cast(actual, expected, explicit); + case BYTE: + case SHORT: + case CHAR: + if (explicit) + return new Cast(actual, expected, true); + + break; + case DEF: + return new Cast(actual, definition.getType("def"), explicit, false, false, true, false); + case OBJECT: + case NUMBER: + case INT_OBJ: + if (internal) + return new Cast(actual, actual, explicit, false, false, false, true); + + break; + case LONG_OBJ: + if (internal) + return new Cast(actual, definition.getType("long"), explicit, false, false, false, true); + + break; + case FLOAT_OBJ: + if (internal) + return new Cast(actual, definition.getType("float"), explicit, false, false, false, true); + + break; + case DOUBLE_OBJ: + if (internal) + return new Cast(actual, definition.getType("double"), explicit, false, false, false, true); + + break; + case BYTE_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("byte"), true, false, false, false, true); + + break; + case SHORT_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("short"), true, false, false, false, true); + + break; + case CHAR_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("char"), true, false, false, false, true); + + break; + } + + break; + case LONG: + switch (expected.sort) { + case FLOAT: + case DOUBLE: + return new Cast(actual, expected, explicit); + case BYTE: + case SHORT: + case CHAR: + case INT: + if (explicit) + return new Cast(actual, expected, true); + + break; + case DEF: + return new Cast(actual, definition.getType("def"), explicit, false, false, true, false); + case OBJECT: + case NUMBER: + case LONG_OBJ: + if (internal) + return new Cast(actual, actual, explicit, false, false, false, true); + + break; + case FLOAT_OBJ: + if (internal) + return new Cast(actual, definition.getType("float"), explicit, false, false, false, true); + + break; + case DOUBLE_OBJ: + if (internal) + return new Cast(actual, definition.getType("double"), explicit, false, false, false, true); + + break; + case BYTE_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("byte"), true, false, false, false, true); + + break; + case SHORT_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("short"), true, false, false, false, true); + + break; + case CHAR_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("char"), true, false, false, false, true); + + break; + case INT_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("int"), true, false, false, false, true); + + break; + } + + break; + case FLOAT: + switch (expected.sort) { + case DOUBLE: + return new Cast(actual, expected, explicit); + case BYTE: + case SHORT: + case CHAR: + case INT: + case FLOAT: + if (explicit) + return new Cast(actual, expected, true); + + break; + case DEF: + return new Cast(actual, definition.getType("def"), explicit, false, false, true, false); + case OBJECT: + case NUMBER: + case FLOAT_OBJ: + if (internal) + return new Cast(actual, actual, explicit, false, false, false, true); + + break; + case DOUBLE_OBJ: + if (internal) + return new Cast(actual, definition.getType("double"), explicit, false, false, false, true); + + break; + case BYTE_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("byte"), true, false, false, false, true); + + break; + case SHORT_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("short"), true, false, false, false, true); + + break; + case CHAR_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("char"), true, false, false, false, true); + + break; + case INT_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("int"), true, false, false, false, true); + + break; + case LONG_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("long"), true, false, false, false, true); + + break; + } + + break; + case DOUBLE: + switch (expected.sort) { + case BYTE: + case SHORT: + case CHAR: + case INT: + case FLOAT: + if (explicit) + return new Cast(actual, expected, true); + + break; + case DEF: + return new Cast(actual, definition.getType("def"), explicit, false, false, true, false); + case OBJECT: + case NUMBER: + case DOUBLE_OBJ: + if (internal) + return new Cast(actual, actual, explicit, false, false, false, true); + + break; + case BYTE_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("byte"), true, false, false, false, true); + + break; + case SHORT_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("short"), true, false, false, false, true); + + break; + case CHAR_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("char"), true, false, false, false, true); + + break; + case INT_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("int"), true, false, false, false, true); + + break; + case LONG_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("long"), true, false, false, false, true); + + break; + case FLOAT_OBJ: + if (explicit && internal) + return new Cast(actual, definition.getType("float"), true, false, false, false, true); + + break; + } + + break; + case OBJECT: + case NUMBER: + switch (expected.sort) { + case BYTE: + if (internal && explicit) + return new Cast(actual, definition.getType("Byte"), true, false, true, false, false); + + break; + case SHORT: + if (internal && explicit) + return new Cast(actual, definition.getType("Short"), true, false, true, false, false); + + break; + case CHAR: + if (internal && explicit) + return new Cast(actual, definition.getType("Character"), true, false, true, false, false); + + break; + case INT: + if (internal && explicit) + return new Cast(actual, definition.getType("Integer"), true, false, true, false, false); + + break; + case LONG: + if (internal && explicit) + return new Cast(actual, definition.getType("Long"), true, false, true, false, false); + + break; + case FLOAT: + if (internal && explicit) + return new Cast(actual, definition.getType("Float"), true, false, true, false, false); + + break; + case DOUBLE: + if (internal && explicit) + return new Cast(actual, definition.getType("Double"), true, false, true, false, false); + + break; + } + + break; + case BOOL_OBJ: + switch (expected.sort) { + case BOOL: + if (internal) + return new Cast(actual, expected, explicit, true, false, false, false); + + break; + } + + break; + case BYTE_OBJ: + switch (expected.sort) { + case BYTE: + case SHORT: + case INT: + case LONG: + case FLOAT: + case DOUBLE: + if (internal) + return new Cast(actual, expected, explicit, true, false, false, false); + + break; + case CHAR: + if (internal && explicit) + return new Cast(actual, expected, true, true, false, false, false); + + break; + } + + break; + case SHORT_OBJ: + switch (expected.sort) { + case SHORT: + case INT: + case LONG: + case FLOAT: + case DOUBLE: + if (internal) + return new Cast(actual, expected, explicit, true, false, false, false); + + break; + case BYTE: + case CHAR: + if (internal && explicit) + return new Cast(actual, expected, true, true, false, false, false); + + break; + } + + break; + case CHAR_OBJ: + switch (expected.sort) { + case CHAR: + case INT: + case LONG: + case FLOAT: + case DOUBLE: + if (internal) + return new Cast(actual, expected, explicit, true, false, false, false); + + break; + case BYTE: + case SHORT: + if (internal && explicit) + return new Cast(actual, expected, true, true, false, false, false); + + break; + } + + break; + case INT_OBJ: + switch (expected.sort) { + case INT: + case LONG: + case FLOAT: + case DOUBLE: + if (internal) + return new Cast(actual, expected, explicit, true, false, false, false); + + break; + case BYTE: + case SHORT: + case CHAR: + if (internal && explicit) + return new Cast(actual, expected, true, true, false, false, false); + + break; + } + + break; + case LONG_OBJ: + switch (expected.sort) { + case LONG: + case FLOAT: + case DOUBLE: + if (internal) + return new Cast(actual, expected, explicit, true, false, false, false); + + break; + case BYTE: + case SHORT: + case CHAR: + case INT: + if (internal && explicit) + return new Cast(actual, expected, true, true, false, false, false); + + break; + } + + break; + case FLOAT_OBJ: + switch (expected.sort) { + case FLOAT: + case DOUBLE: + if (internal) + return new Cast(actual, expected, explicit, true, false, false, false); + + break; + case BYTE: + case SHORT: + case CHAR: + case INT: + case LONG: + if (internal && explicit) + return new Cast(actual, expected, true, true, false, false, false); + + break; + } + + break; + case DOUBLE_OBJ: + switch (expected.sort) { + case FLOAT: + case DOUBLE: + if (internal) + return new Cast(actual, expected, explicit, true, false, false, false); + + break; + case BYTE: + case SHORT: + case CHAR: + case INT: + case LONG: + if (internal && explicit) + return new Cast(actual, expected, true, true, false, false, false); + + break; + } + + break; + case DEF: + switch (expected.sort) { + case BOOL: + case BYTE: + case SHORT: + case CHAR: + case INT: + case LONG: + case FLOAT: + case DOUBLE: + return new Cast(actual, expected, true, true, false, false, false); + } + + break; + case STRING: + switch (expected.sort) { + case CHAR: + if (explicit) + return new Cast(actual, expected, true, false, false, false, false); + + break; + } + + break; } if (expected.clazz.isAssignableFrom(actual.clazz) || ((explicit || expected.sort == Sort.DEF) && actual.clazz.isAssignableFrom(expected.clazz))) { - return cast; + return new Cast(actual, expected, explicit); } else { throw new ClassCastException("Error" + location + ": Cannot cast from [" + actual.name + "] to [" + expected.name + "]."); } } public static Object constCast(final String location, final Object constant, final Cast cast) { - if (cast instanceof Transform) { - final Transform transform = (Transform)cast; - return invokeTransform(location, transform, constant); + final Sort fsort = cast.from.sort; + final Sort tsort = cast.to.sort; + + if (fsort == tsort) { + return constant; + } else if (fsort == Sort.STRING && tsort == Sort.CHAR) { + return Utility.StringTochar((String)constant); + } else if (fsort == Sort.CHAR && tsort == Sort.STRING) { + return Utility.charToString((char)constant); + } else if (fsort.numeric && tsort.numeric) { + final Number number; + + if (fsort == Sort.CHAR) { + number = (int)(char)constant; + } else { + number = (Number)constant; + } + + switch (tsort) { + case BYTE: return number.byteValue(); + case SHORT: return number.shortValue(); + case CHAR: return (char)number.intValue(); + case INT: return number.intValue(); + case LONG: return number.longValue(); + case FLOAT: return number.floatValue(); + case DOUBLE: return number.doubleValue(); + default: + throw new IllegalStateException("Error" + location + ": Cannot cast from " + + "[" + cast.from.clazz.getCanonicalName() + "] to [" + cast.to.clazz.getCanonicalName() + "]."); + } } else { - final Sort fsort = cast.from.sort; - final Sort tsort = cast.to.sort; - - if (fsort == tsort) { - return constant; - } else if (fsort.numeric && tsort.numeric) { - Number number; - - if (fsort == Sort.CHAR) { - number = (int)(char)constant; - } else { - number = (Number)constant; - } - - switch (tsort) { - case BYTE: return number.byteValue(); - case SHORT: return number.shortValue(); - case CHAR: return (char)number.intValue(); - case INT: return number.intValue(); - case LONG: return number.longValue(); - case FLOAT: return number.floatValue(); - case DOUBLE: return number.doubleValue(); - default: - throw new IllegalStateException("Error" + location + ": Cannot cast from " + - "[" + cast.from.clazz.getCanonicalName() + "] to [" + cast.to.clazz.getCanonicalName() + "]."); - } - } else { - throw new IllegalStateException("Error" + location + ": Cannot cast from " + - "[" + cast.from.clazz.getCanonicalName() + "] to [" + cast.to.clazz.getCanonicalName() + "]."); - } - } - } - - private static Object invokeTransform(final String location, final Transform transform, final Object object) { - final Method method = transform.method; - final java.lang.reflect.Method jmethod = method.reflect; - final int modifiers = jmethod.getModifiers(); - - try { - if (java.lang.reflect.Modifier.isStatic(modifiers)) { - return jmethod.invoke(null, object); - } else { - return jmethod.invoke(object); - } - } catch (final IllegalAccessException | IllegalArgumentException | - InvocationTargetException | NullPointerException | ExceptionInInitializerError exception) { - throw new ClassCastException( - "Error" + location + ": Cannot cast from [" + transform.from.name + "] to [" + transform.to.name + "]."); + throw new IllegalStateException("Error" + location + ": Cannot cast from " + + "[" + cast.from.clazz.getCanonicalName() + "] to [" + cast.to.clazz.getCanonicalName() + "]."); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java index 889328e58db..1d804a264ae 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java @@ -972,6 +972,10 @@ public final class Def { // Conversion methods for Def to primitive types. + public static boolean DefToboolean(final Object value) { + return (boolean)value; + } + public static byte DefTobyteImplicit(final Object value) { return (byte)value; } @@ -1052,79 +1056,6 @@ public final class Def { } } - public static Byte DefToByteImplicit(final Object value) { - return (Byte)value; - } - - public static Short DefToShortImplicit(final Object value) { - if (value == null) { - return null; - } else if (value instanceof Byte) { - return ((Byte)value).shortValue(); - } else { - return (Short)value; - } - } - - public static Character DefToCharacterImplicit(final Object value) { - if (value == null) { - return null; - } else if (value instanceof Byte) { - return (char)(byte)value; - } else { - return (Character)value; - } - } - - public static Integer DefToIntegerImplicit(final Object value) { - if (value == null) { - return null; - } else if (value instanceof Byte || value instanceof Short) { - return ((Number)value).intValue(); - } else if (value instanceof Character) { - return (int)(char)value; - } else { - return (Integer)value; - } - } - - public static Long DefToLongImplicit(final Object value) { - if (value == null) { - return null; - } else if (value instanceof Byte || value instanceof Short || value instanceof Integer) { - return ((Number)value).longValue(); - } else if (value instanceof Character) { - return (long)(char)value; - } else { - return (Long)value; - } - } - - public static Float DefToFloatImplicit(final Object value) { - if (value == null) { - return null; - } else if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long) { - return ((Number)value).floatValue(); - } else if (value instanceof Character) { - return (float)(char)value; - } else { - return (Float)value; - } - } - - public static Double DefToDoubleImplicit(final Object value) { - if (value == null) { - return null; - } else if (value instanceof Byte || value instanceof Short || - value instanceof Integer || value instanceof Long || value instanceof Float) { - return ((Number)value).doubleValue(); - } else if (value instanceof Character) { - return (double)(char)value; - } else { - return (Double)value; - } - } - public static byte DefTobyteExplicit(final Object value) { if (value instanceof Character) { return (byte)(char)value; @@ -1180,74 +1111,4 @@ public final class Def { return ((Number)value).doubleValue(); } } - - public static Byte DefToByteExplicit(final Object value) { - if (value == null) { - return null; - } else if (value instanceof Character) { - return (byte)(char)value; - } else { - return ((Number)value).byteValue(); - } - } - - public static Short DefToShortExplicit(final Object value) { - if (value == null) { - return null; - } else if (value instanceof Character) { - return (short)(char)value; - } else { - return ((Number)value).shortValue(); - } - } - - public static Character DefToCharacterExplicit(final Object value) { - if (value == null) { - return null; - } else if (value instanceof Character) { - return ((Character)value); - } else { - return (char)((Number)value).intValue(); - } - } - - public static Integer DefToIntegerExplicit(final Object value) { - if (value == null) { - return null; - } else if (value instanceof Character) { - return (int)(char)value; - } else { - return ((Number)value).intValue(); - } - } - - public static Long DefToLongExplicit(final Object value) { - if (value == null) { - return null; - } else if (value instanceof Character) { - return (long)(char)value; - } else { - return ((Number)value).longValue(); - } - } - - public static Float DefToFloatExplicit(final Object value) { - if (value == null) { - return null; - } else if (value instanceof Character) { - return (float)(char)value; - } else { - return ((Number)value).floatValue(); - } - } - - public static Double DefToDoubleExplicit(final Object value) { - if (value == null) { - return null; - } else if (value instanceof Character) { - return (double)(char)value; - } else { - return ((Number)value).doubleValue(); - } - } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java index 95d169cb886..f20393fb6ed 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java @@ -308,50 +308,32 @@ public final class Definition { public final Type from; public final Type to; public final boolean explicit; + public final boolean unboxFrom; + public final boolean unboxTo; + public final boolean boxFrom; + public final boolean boxTo; public Cast(final Type from, final Type to, final boolean explicit) { this.from = from; this.to = to; this.explicit = explicit; + this.unboxFrom = false; + this.unboxTo = false; + this.boxFrom = false; + this.boxTo = false; } - @Override - public boolean equals(final Object object) { - if (this == object) { - return true; - } - - if (object == null || getClass() != object.getClass()) { - return false; - } - - final Cast cast = (Cast)object; - - return from.equals(cast.from) && to.equals(cast.to) && explicit == cast.explicit; + public Cast(final Type from, final Type to, final boolean explicit, + final boolean unboxFrom, final boolean unboxTo, final boolean boxFrom, final boolean boxTo) { + this.from = from; + this.to = to; + this.explicit = explicit; + this.unboxFrom = unboxFrom; + this.unboxTo = unboxTo; + this.boxFrom = boxFrom; + this.boxTo = boxTo; } - @Override - public int hashCode() { - int result = from.hashCode(); - result = 31 * result + to.hashCode(); - result = 31 * result + (explicit ? 1 : 0); - - return result; - } - } - - public static final class Transform extends Cast { - public final Method method; - public final Type upcast; - public final Type downcast; - - public Transform(final Cast cast, Method method, final Type upcast, final Type downcast) { - super(cast.from, cast.to, cast.explicit); - - this.method = method; - this.upcast = upcast; - this.downcast = downcast; - } } public static final class RuntimeClass { @@ -367,7 +349,6 @@ public final class Definition { } } - final Map transformsMap; final Map, RuntimeClass> runtimeMap; private final Map structsMap; private final Map simpleTypesMap; @@ -375,7 +356,6 @@ public final class Definition { private Definition() { structsMap = new HashMap<>(); simpleTypesMap = new HashMap<>(); - transformsMap = new HashMap<>(); runtimeMap = new HashMap<>(); // parse the classes and return hierarchy (map of class name -> superclasses/interfaces) @@ -386,7 +366,6 @@ public final class Definition { for (Map.Entry> clazz : hierarchy.entrySet()) { copyStruct(clazz.getKey(), clazz.getValue()); } - addTransforms(); // precompute runtime classes for (Struct struct : structsMap.values()) { addRuntimeClass(struct); @@ -401,7 +380,6 @@ public final class Definition { } this.structsMap = Collections.unmodifiableMap(structs); - this.transformsMap = Collections.unmodifiableMap(definition.transformsMap); this.runtimeMap = Collections.unmodifiableMap(definition.runtimeMap); this.simpleTypesMap = Collections.unmodifiableMap(definition.simpleTypesMap); } @@ -503,130 +481,6 @@ public final class Definition { } } - private void addTransforms() { - Type booleanType = getType("boolean"); - Type objectType = getType("Object"); - Type defType = getType("def"); - Type booleanobjType = getType("Boolean"); - Type byteType = getType("byte"); - Type shortType = getType("short"); - Type intType = getType("int"); - Type charType = getType("char"); - Type longType = getType("long"); - Type floatType = getType("float"); - Type doubleType = getType("double"); - Type numberType = getType("Number"); - Type byteobjType = getType("Byte"); - Type shortobjType = getType("Short"); - Type charobjType = getType("Character"); - Type intobjType = getType("Integer"); - Type longobjType = getType("Long"); - Type floatobjType = getType("Float"); - Type doubleobjType = getType("Double"); - Type stringType = getType("String"); - - addTransform(booleanType, objectType, "Boolean", "valueOf", true, false); - addTransform(booleanType, defType, "Boolean", "valueOf", true, false); - addTransform(booleanType, booleanobjType, "Boolean", "valueOf", true, false); - - addTransform(byteType, shortType, false); - addTransform(byteType, charType, true); - addTransform(byteType, intType, false); - addTransform(byteType, longType, false); - addTransform(byteType, floatType, false); - addTransform(byteType, doubleType, false); - addTransform(byteType, objectType, "Byte", "valueOf", true, false); - addTransform(byteType, defType, "Byte", "valueOf", true, false); - addTransform(byteType, numberType, "Byte", "valueOf", true, false); - addTransform(byteType, byteobjType, "Byte", "valueOf", true, false); - - addTransform(shortType, byteType, true); - addTransform(shortType, charType, true); - addTransform(shortType, intType, false); - addTransform(shortType, longType, false); - addTransform(shortType, floatType, false); - addTransform(shortType, doubleType, false); - addTransform(shortType, objectType, "Short", "valueOf", true, false); - addTransform(shortType, defType, "Short", "valueOf", true, false); - addTransform(shortType, numberType, "Short", "valueOf", true, false); - addTransform(shortType, shortobjType, "Short", "valueOf", true, false); - - addTransform(charType, byteType, true); - addTransform(charType, shortType, true); - addTransform(charType, intType, false); - addTransform(charType, longType, false); - addTransform(charType, floatType, false); - addTransform(charType, doubleType, false); - addTransform(charType, objectType, "Character", "valueOf", true, false); - addTransform(charType, defType, "Character", "valueOf", true, false); - addTransform(charType, numberType, "Utility", "charToInteger", true, false); - addTransform(charType, charobjType, "Character", "valueOf", true, false); - addTransform(charType, stringType, "Utility", "charToString", true, true); - - addTransform(intType, byteType, true); - addTransform(intType, shortType, true); - addTransform(intType, charType, true); - addTransform(intType, longType, false); - addTransform(intType, floatType, false); - addTransform(intType, doubleType, false); - addTransform(intType, objectType, "Integer", "valueOf", true, false); - addTransform(intType, defType, "Integer", "valueOf", true, false); - addTransform(intType, numberType, "Integer", "valueOf", true, false); - addTransform(intType, intobjType, "Integer", "valueOf", true, false); - - addTransform(longType, byteType, true); - addTransform(longType, shortType, true); - addTransform(longType, charType, true); - addTransform(longType, intType, false); - addTransform(longType, floatType, false); - addTransform(longType, doubleType, false); - addTransform(longType, objectType, "Long", "valueOf", true, false); - addTransform(longType, defType, "Long", "valueOf", true, false); - addTransform(longType, numberType, "Long", "valueOf", true, false); - addTransform(longType, longobjType, "Long", "valueOf", true, false); - - addTransform(floatType, byteType, true); - addTransform(floatType, shortType, true); - addTransform(floatType, charType, true); - addTransform(floatType, intType, true); - addTransform(floatType, longType, false); - addTransform(floatType, doubleType, false); - addTransform(floatType, objectType, "Float", "valueOf", true, false); - addTransform(floatType, defType, "Float", "valueOf", true, false); - addTransform(floatType, numberType, "Float", "valueOf", true, false); - addTransform(floatType, floatobjType, "Float", "valueOf", true, false); - - addTransform(doubleType, byteType, true); - addTransform(doubleType, shortType, true); - addTransform(doubleType, charType, true); - addTransform(doubleType, intType, true); - addTransform(doubleType, longType, true); - addTransform(doubleType, floatType, false); - addTransform(doubleType, objectType, "Double", "valueOf", true, false); - addTransform(doubleType, defType, "Double", "valueOf", true, false); - addTransform(doubleType, numberType, "Double", "valueOf", true, false); - addTransform(doubleType, doubleobjType, "Double", "valueOf", true, false); - - addTransform(defType, booleanType, "Boolean", "booleanValue", false, false); - addTransform(defType, byteType, "Def", "DefTobyteImplicit", true, false); - addTransform(defType, shortType, "Def", "DefToshortImplicit", true, false); - addTransform(defType, charType, "Def", "DefTocharImplicit", true, false); - addTransform(defType, intType, "Def", "DefTointImplicit", true, false); - addTransform(defType, longType, "Def", "DefTolongImplicit", true, false); - addTransform(defType, floatType, "Def", "DefTofloatImplicit", true, false); - addTransform(defType, doubleType, "Def", "DefTodoubleImplicit", true, false); - addTransform(defType, byteType, "Def", "DefTobyteExplicit", true, true); - addTransform(defType, shortType, "Def", "DefToshortExplicit", true, true); - addTransform(defType, charType, "Def", "DefTocharExplicit", true, true); - addTransform(defType, intType, "Def", "DefTointExplicit", true, true); - addTransform(defType, longType, "Def", "DefTolongExplicit", true, true); - addTransform(defType, floatType, "Def", "DefTofloatExplicit", true, true); - addTransform(defType, doubleType, "Def", "DefTodoubleExplicit", true, true); - - addTransform(stringType, charType, "Utility", "StringTochar", true, true); - addTransform(stringType, charobjType, "Utility", "StringToCharacter", true, true); - } - private final void addStruct(final String name, final Class clazz) { if (!name.matches("^[_a-zA-Z][<>,_a-zA-Z0-9]*$")) { throw new IllegalArgumentException("Invalid struct name [" + name + "]."); @@ -960,137 +814,6 @@ public final class Definition { } } - private final void addTransform(final Type from, final Type to, final boolean explicit) { - if (from.equals(to)) { - throw new IllegalArgumentException("Transform cannot" + - " have cast type from [" + from.name + "] be the same as cast type to [" + to.name + "]."); - } - - if (!from.sort.primitive || !to.sort.primitive) { - throw new IllegalArgumentException("Only transforms between two primitives may be a simple cast, but" + - "found [" + from.name + "] and [" + to.name + "]."); - } - - final Cast cast = new Cast(from, to, explicit); - - if (transformsMap.containsKey(cast)) { - throw new IllegalArgumentException("Transform with " + - " cast type from [" + from.name + "] to cast type to [" + to.name + "] already defined."); - } - - transformsMap.put(cast, cast); - } - - private final void addTransform(final Type from, final Type to, final String struct, - final String name, final boolean statik, final boolean explicit) { - final Struct owner = structsMap.get(struct); - - if (owner == null) { - throw new IllegalArgumentException("Owner struct [" + struct + "] not defined for" + - " transform with cast type from [" + from.name + "] and cast type to [" + to.name + "]."); - } - - if (from.equals(to)) { - throw new IllegalArgumentException("Transform with owner struct [" + owner.name + "] cannot" + - " have cast type from [" + from.name + "] be the same as cast type to [" + to.name + "]."); - } - - final Cast cast = new Cast(from, to, explicit); - - if (transformsMap.containsKey(cast)) { - throw new IllegalArgumentException("Transform with owner struct [" + owner.name + "]" + - " and cast type from [" + from.name + "] to cast type to [" + to.name + "] already defined."); - } - - final Cast transform; - - final Method method; - Type upcast = null; - Type downcast = null; - - // transforms are implicitly arity of 0, unless a static method where its 1 (receiver passed) - final MethodKey methodKey = new MethodKey(name, statik ? 1 : 0); - - if (statik) { - method = owner.staticMethods.get(methodKey); - - if (method == null) { - throw new IllegalArgumentException("Transform with owner struct [" + owner.name + "]" + - " and cast type from [" + from.name + "] to cast type to [" + to.name + - "] using a function [" + name + "] that is not defined."); - } - - if (method.arguments.size() != 1) { - throw new IllegalArgumentException("Transform with owner struct [" + owner.name + "]" + - " and cast type from [" + from.name + "] to cast type to [" + to.name + - "] using function [" + name + "] does not have a single type argument."); - } - - Type argument = method.arguments.get(0); - - if (!argument.clazz.isAssignableFrom(from.clazz)) { - if (from.clazz.isAssignableFrom(argument.clazz)) { - upcast = argument; - } else { - throw new ClassCastException("Transform with owner struct [" + owner.name + "]" + - " and cast type from [" + from.name + "] to cast type to [" + to.name + "] using" + - " function [" + name + "] cannot cast from type to the function input argument type."); - } - } - - final Type rtn = method.rtn; - - if (!to.clazz.isAssignableFrom(rtn.clazz)) { - if (rtn.clazz.isAssignableFrom(to.clazz)) { - downcast = to; - } else { - throw new ClassCastException("Transform with owner struct [" + owner.name + "]" + - " and cast type from [" + from.name + "] to cast type to [" + to.name + "] using" + - " function [" + name + "] cannot cast to type to the function return argument type."); - } - } - } else { - method = owner.methods.get(methodKey); - - if (method == null) { - throw new IllegalArgumentException("Transform with owner struct [" + owner.name + "]" + - " and cast type from [" + from.name + "] to cast type to [" + to.name + - "] using a method [" + name + "] that is not defined."); - } - - if (!method.arguments.isEmpty()) { - throw new IllegalArgumentException("Transform with owner struct [" + owner.name + "]" + - " and cast type from [" + from.name + "] to cast type to [" + to.name + - "] using method [" + name + "] does not have a single type argument."); - } - - if (!owner.clazz.isAssignableFrom(from.clazz)) { - if (from.clazz.isAssignableFrom(owner.clazz)) { - upcast = getType(owner.name); - } else { - throw new ClassCastException("Transform with owner struct [" + owner.name + "]" + - " and cast type from [" + from.name + "] to cast type to [" + to.name + "] using" + - " method [" + name + "] cannot cast from type to the method input argument type."); - } - } - - final Type rtn = method.rtn; - - if (!to.clazz.isAssignableFrom(rtn.clazz)) { - if (rtn.clazz.isAssignableFrom(to.clazz)) { - downcast = to; - } else { - throw new ClassCastException("Transform with owner struct [" + owner.name + "]" + - " and cast type from [" + from.name + "] to cast type to [" + to.name + "]" + - " using method [" + name + "] cannot cast to type to the method return argument type."); - } - } - } - - transform = new Transform(cast, method, upcast, downcast); - transformsMap.put(cast, transform); - } - /** * Precomputes a more efficient structure for dynamic method/field access. */ diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java index cda8c23e3bf..52070ee3f77 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java @@ -21,7 +21,6 @@ package org.elasticsearch.painless; import org.elasticsearch.painless.Definition.Cast; import org.elasticsearch.painless.Definition.Sort; -import org.elasticsearch.painless.Definition.Transform; import org.elasticsearch.painless.Definition.Type; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.Label; @@ -34,6 +33,7 @@ import java.util.ArrayList; import java.util.Deque; import java.util.List; +import static org.elasticsearch.painless.WriterConstants.CHAR_TO_STRING; import static org.elasticsearch.painless.WriterConstants.DEF_ADD_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_AND_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_DIV_CALL; @@ -43,6 +43,22 @@ import static org.elasticsearch.painless.WriterConstants.DEF_OR_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_REM_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_RSH_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_SUB_CALL; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_BOOLEAN; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_BYTE_EXPLICIT; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_BYTE_IMPLICIT; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_CHAR_EXPLICIT; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_CHAR_IMPLICIT; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_DOUBLE_EXPLICIT; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_DOUBLE_IMPLICIT; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_FLOAT_EXPLICIT; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_FLOAT_IMPLICIT; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_INT_EXPLICIT; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_INT_IMPLICIT; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_LONG_EXPLICIT; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_LONG_IMPLICIT; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_SHORT_EXPLICIT; +import static org.elasticsearch.painless.WriterConstants.DEF_TO_SHORT_IMPLICIT; +import static org.elasticsearch.painless.WriterConstants.DEF_TYPE; import static org.elasticsearch.painless.WriterConstants.DEF_USH_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_XOR_CALL; import static org.elasticsearch.painless.WriterConstants.INDY_STRING_CONCAT_BOOTSTRAP_HANDLE; @@ -59,7 +75,9 @@ import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_APPEND_ST import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_CONSTRUCTOR; import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_TOSTRING; import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_TYPE; +import static org.elasticsearch.painless.WriterConstants.STRING_TO_CHAR; import static org.elasticsearch.painless.WriterConstants.STRING_TYPE; +import static org.elasticsearch.painless.WriterConstants.UTILITY_TYPE; /** * Extension of {@link GeneratorAdapter} with some utility methods. @@ -96,45 +114,72 @@ public final class MethodWriter extends GeneratorAdapter { visitVarInsn(Opcodes.ILOAD, slot); push(0); ifICmp(GeneratorAdapter.GT, end); - throwException(PAINLESS_ERROR_TYPE, - "The maximum number of statements that can be executed in a loop has been reached."); + throwException(PAINLESS_ERROR_TYPE, "The maximum number of statements that can be executed in a loop has been reached."); mark(end); } } public void writeCast(final Cast cast) { - if (cast instanceof Transform) { - final Transform transform = (Transform)cast; - - if (transform.upcast != null) { - checkCast(transform.upcast.type); - } - - if (java.lang.reflect.Modifier.isStatic(transform.method.reflect.getModifiers())) { - invokeStatic(transform.method.owner.type, transform.method.method); - } else if (java.lang.reflect.Modifier.isInterface(transform.method.owner.clazz.getModifiers())) { - invokeInterface(transform.method.owner.type, transform.method.method); - } else { - invokeVirtual(transform.method.owner.type, transform.method.method); - } - - if (transform.downcast != null) { - checkCast(transform.downcast.type); - } - } else if (cast != null) { + if (cast != null) { final Type from = cast.from; final Type to = cast.to; - if (from.equals(to)) { - return; - } - - if (from.sort.numeric && from.sort.primitive && to.sort.numeric && to.sort.primitive) { - cast(from.type, to.type); - } else { - if (!to.clazz.isAssignableFrom(from.clazz)) { - checkCast(to.type); + if (from.sort == Sort.CHAR && to.sort == Sort.STRING) { + invokeStatic(UTILITY_TYPE, CHAR_TO_STRING); + } else if (from.sort == Sort.STRING && to.sort == Sort.CHAR) { + invokeStatic(UTILITY_TYPE, STRING_TO_CHAR); + } else if (cast.unboxFrom) { + if (from.sort == Sort.DEF) { + if (cast.explicit) { + if (to.sort == Sort.BOOL) invokeStatic(DEF_TYPE, DEF_TO_BOOLEAN); + else if (to.sort == Sort.BYTE) invokeStatic(DEF_TYPE, DEF_TO_BYTE_EXPLICIT); + else if (to.sort == Sort.SHORT) invokeStatic(DEF_TYPE, DEF_TO_SHORT_EXPLICIT); + else if (to.sort == Sort.CHAR) invokeStatic(DEF_TYPE, DEF_TO_CHAR_EXPLICIT); + else if (to.sort == Sort.INT) invokeStatic(DEF_TYPE, DEF_TO_INT_EXPLICIT); + else if (to.sort == Sort.LONG) invokeStatic(DEF_TYPE, DEF_TO_LONG_EXPLICIT); + else if (to.sort == Sort.FLOAT) invokeStatic(DEF_TYPE, DEF_TO_FLOAT_EXPLICIT); + else if (to.sort == Sort.DOUBLE) invokeStatic(DEF_TYPE, DEF_TO_DOUBLE_EXPLICIT); + else throw new IllegalStateException("Illegal tree structure."); + } else { + if (to.sort == Sort.BOOL) invokeStatic(DEF_TYPE, DEF_TO_BOOLEAN); + else if (to.sort == Sort.BYTE) invokeStatic(DEF_TYPE, DEF_TO_BYTE_IMPLICIT); + else if (to.sort == Sort.SHORT) invokeStatic(DEF_TYPE, DEF_TO_SHORT_IMPLICIT); + else if (to.sort == Sort.CHAR) invokeStatic(DEF_TYPE, DEF_TO_CHAR_IMPLICIT); + else if (to.sort == Sort.INT) invokeStatic(DEF_TYPE, DEF_TO_INT_IMPLICIT); + else if (to.sort == Sort.LONG) invokeStatic(DEF_TYPE, DEF_TO_LONG_IMPLICIT); + else if (to.sort == Sort.FLOAT) invokeStatic(DEF_TYPE, DEF_TO_FLOAT_IMPLICIT); + else if (to.sort == Sort.DOUBLE) invokeStatic(DEF_TYPE, DEF_TO_DOUBLE_IMPLICIT); + else throw new IllegalStateException("Illegal tree structure."); + } + } else { + unbox(from.type); + writeCast(from, to); } + } else if (cast.unboxTo) { + writeCast(from, to); + unbox(to.type); + } else if (cast.boxFrom) { + box(from.type); + writeCast(from, to); + } else if (cast.boxTo) { + writeCast(from, to); + box(to.type); + } else { + writeCast(from, to); + } + } + } + + private void writeCast(final Type from, final Type to) { + if (from.equals(to)) { + return; + } + + if (from.sort.numeric && from.sort.primitive && to.sort.numeric && to.sort.primitive) { + cast(from.type, to.type); + } else { + if (!to.clazz.isAssignableFrom(from.clazz)) { + checkCast(to.type); } } } @@ -146,7 +191,7 @@ public final class MethodWriter extends GeneratorAdapter { visitJumpInsn(Opcodes.IFEQ, fals); } } - + public void writeNewStrings() { if (INDY_STRING_CONCAT_BOOTSTRAP_HANDLE != null) { // Java 9+: we just push our argument collector onto deque @@ -200,31 +245,29 @@ public final class MethodWriter extends GeneratorAdapter { } } - public void writeBinaryInstruction(final Definition definition, - final String location, - final Type type, final Operation operation) { + public void writeBinaryInstruction(final String location, final Type type, final Operation operation) { final Sort sort = type.sort; - + if ((sort == Sort.FLOAT || sort == Sort.DOUBLE) && (operation == Operation.LSH || operation == Operation.USH || operation == Operation.RSH || operation == Operation.BWAND || operation == Operation.XOR || operation == Operation.BWOR)) { throw new IllegalStateException("Error " + location + ": Illegal tree structure."); } - + if (sort == Sort.DEF) { switch (operation) { - case MUL: invokeStatic(definition.getType("Def").type, DEF_MUL_CALL); break; - case DIV: invokeStatic(definition.getType("Def").type, DEF_DIV_CALL); break; - case REM: invokeStatic(definition.getType("Def").type, DEF_REM_CALL); break; - case ADD: invokeStatic(definition.getType("Def").type, DEF_ADD_CALL); break; - case SUB: invokeStatic(definition.getType("Def").type, DEF_SUB_CALL); break; - case LSH: invokeStatic(definition.getType("Def").type, DEF_LSH_CALL); break; - case USH: invokeStatic(definition.getType("Def").type, DEF_RSH_CALL); break; - case RSH: invokeStatic(definition.getType("Def").type, DEF_USH_CALL); break; - case BWAND: invokeStatic(definition.getType("Def").type, DEF_AND_CALL); break; - case XOR: invokeStatic(definition.getType("Def").type, DEF_XOR_CALL); break; - case BWOR: invokeStatic(definition.getType("Def").type, DEF_OR_CALL); break; + case MUL: invokeStatic(DEF_TYPE, DEF_MUL_CALL); break; + case DIV: invokeStatic(DEF_TYPE, DEF_DIV_CALL); break; + case REM: invokeStatic(DEF_TYPE, DEF_REM_CALL); break; + case ADD: invokeStatic(DEF_TYPE, DEF_ADD_CALL); break; + case SUB: invokeStatic(DEF_TYPE, DEF_SUB_CALL); break; + case LSH: invokeStatic(DEF_TYPE, DEF_LSH_CALL); break; + case USH: invokeStatic(DEF_TYPE, DEF_RSH_CALL); break; + case RSH: invokeStatic(DEF_TYPE, DEF_USH_CALL); break; + case BWAND: invokeStatic(DEF_TYPE, DEF_AND_CALL); break; + case XOR: invokeStatic(DEF_TYPE, DEF_XOR_CALL); break; + case BWOR: invokeStatic(DEF_TYPE, DEF_OR_CALL); break; default: throw new IllegalStateException("Error " + location + ": Illegal tree structure."); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java index 559e909ed77..c8429f9458a 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java @@ -469,18 +469,6 @@ public class Utility { return value.charAt(0); } - public static Character StringToCharacter(final String value) { - if (value == null) { - return null; - } - - if (value.length() != 1) { - throw new ClassCastException("Cannot cast [String] with length greater than one to [Character]."); - } - - return value.charAt(0); - } - public static boolean checkEquals(final Object left, final Object right) { if (left != null) { return left.equals(right); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java index d167646e9dd..6330e1603c5 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java @@ -38,7 +38,7 @@ public final class WriterConstants { public final static String BASE_CLASS_NAME = Executable.class.getName(); public final static Type BASE_CLASS_TYPE = Type.getType(Executable.class); - + public final static String CLASS_NAME = BASE_CLASS_NAME + "$Script"; public final static Type CLASS_TYPE = Type.getObjectType(CLASS_NAME.replace('.', '/')); @@ -55,6 +55,10 @@ public final class WriterConstants { public final static Type MAP_TYPE = Type.getType(Map.class); public final static Method MAP_GET = getAsmMethod(Object.class, "get", Object.class); + public final static Type UTILITY_TYPE = Type.getType(Utility.class); + public final static Method STRING_TO_CHAR = getAsmMethod(char.class, "StringTochar", String.class); + public final static Method CHAR_TO_STRING = getAsmMethod(String.class, "charToString", char.class); + /** dynamic callsite bootstrap signature */ public final static MethodType DEF_BOOTSTRAP_TYPE = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, int.class); @@ -62,19 +66,36 @@ public final class WriterConstants { new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(DefBootstrap.class), "bootstrap", DEF_BOOTSTRAP_TYPE.toMethodDescriptorString()); - public final static Method DEF_NOT_CALL = getAsmMethod(Object.class, "not", Object.class); - public final static Method DEF_NEG_CALL = getAsmMethod(Object.class, "neg", Object.class); - public final static Method DEF_MUL_CALL = getAsmMethod(Object.class, "mul", Object.class, Object.class); - public final static Method DEF_DIV_CALL = getAsmMethod(Object.class, "div", Object.class, Object.class); - public final static Method DEF_REM_CALL = getAsmMethod(Object.class, "rem", Object.class, Object.class); - public final static Method DEF_ADD_CALL = getAsmMethod(Object.class, "add", Object.class, Object.class); - public final static Method DEF_SUB_CALL = getAsmMethod(Object.class, "sub", Object.class, Object.class); - public final static Method DEF_LSH_CALL = getAsmMethod(Object.class, "lsh", Object.class, int.class); - public final static Method DEF_RSH_CALL = getAsmMethod(Object.class, "rsh", Object.class, int.class); - public final static Method DEF_USH_CALL = getAsmMethod(Object.class, "ush", Object.class, int.class); - public final static Method DEF_AND_CALL = getAsmMethod(Object.class, "and", Object.class, Object.class); - public final static Method DEF_XOR_CALL = getAsmMethod(Object.class, "xor", Object.class, Object.class); - public final static Method DEF_OR_CALL = getAsmMethod(Object.class, "or" , Object.class, Object.class); + + public final static Type DEF_TYPE = Type.getType(Def.class); + public final static Method DEF_TO_BOOLEAN = getAsmMethod(boolean.class, "DefToboolean" , Object.class); + public final static Method DEF_TO_BYTE_IMPLICIT = getAsmMethod(byte.class , "DefTobyteImplicit" , Object.class); + public final static Method DEF_TO_SHORT_IMPLICIT = getAsmMethod(short.class , "DefToshortImplicit" , Object.class); + public final static Method DEF_TO_CHAR_IMPLICIT = getAsmMethod(char.class , "DefTocharImplicit" , Object.class); + public final static Method DEF_TO_INT_IMPLICIT = getAsmMethod(int.class , "DefTointImplicit" , Object.class); + public final static Method DEF_TO_LONG_IMPLICIT = getAsmMethod(long.class , "DefTolongImplicit" , Object.class); + public final static Method DEF_TO_FLOAT_IMPLICIT = getAsmMethod(float.class , "DefTofloatImplicit" , Object.class); + public final static Method DEF_TO_DOUBLE_IMPLICIT = getAsmMethod(double.class , "DefTodoubleImplicit", Object.class); + public final static Method DEF_TO_BYTE_EXPLICIT = getAsmMethod(byte.class , "DefTobyteExplicit" , Object.class); + public final static Method DEF_TO_SHORT_EXPLICIT = getAsmMethod(short.class , "DefToshortExplicit" , Object.class); + public final static Method DEF_TO_CHAR_EXPLICIT = getAsmMethod(char.class , "DefTocharExplicit" , Object.class); + public final static Method DEF_TO_INT_EXPLICIT = getAsmMethod(int.class , "DefTointExplicit" , Object.class); + public final static Method DEF_TO_LONG_EXPLICIT = getAsmMethod(long.class , "DefTolongExplicit" , Object.class); + public final static Method DEF_TO_FLOAT_EXPLICIT = getAsmMethod(float.class , "DefTofloatExplicit" , Object.class); + public final static Method DEF_TO_DOUBLE_EXPLICIT = getAsmMethod(double.class , "DefTodoubleExplicit", Object.class); + public final static Method DEF_NOT_CALL = getAsmMethod(Object.class , "not", Object.class); + public final static Method DEF_NEG_CALL = getAsmMethod(Object.class , "neg", Object.class); + public final static Method DEF_MUL_CALL = getAsmMethod(Object.class , "mul", Object.class, Object.class); + public final static Method DEF_DIV_CALL = getAsmMethod(Object.class , "div", Object.class, Object.class); + public final static Method DEF_REM_CALL = getAsmMethod(Object.class , "rem", Object.class, Object.class); + public final static Method DEF_ADD_CALL = getAsmMethod(Object.class , "add", Object.class, Object.class); + public final static Method DEF_SUB_CALL = getAsmMethod(Object.class , "sub", Object.class, Object.class); + public final static Method DEF_LSH_CALL = getAsmMethod(Object.class , "lsh", Object.class, int.class); + public final static Method DEF_RSH_CALL = getAsmMethod(Object.class , "rsh", Object.class, int.class); + public final static Method DEF_USH_CALL = getAsmMethod(Object.class , "ush", Object.class, int.class); + public final static Method DEF_AND_CALL = getAsmMethod(Object.class , "and", Object.class, Object.class); + public final static Method DEF_XOR_CALL = getAsmMethod(Object.class , "xor", Object.class, Object.class); + public final static Method DEF_OR_CALL = getAsmMethod(Object.class , "or" , Object.class, Object.class); public final static Method DEF_EQ_CALL = getAsmMethod(boolean.class, "eq" , Object.class, Object.class); public final static Method DEF_LT_CALL = getAsmMethod(boolean.class, "lt" , Object.class, Object.class); public final static Method DEF_LTE_CALL = getAsmMethod(boolean.class, "lte", Object.class, Object.class); @@ -98,9 +119,9 @@ public final class WriterConstants { } INDY_STRING_CONCAT_BOOTSTRAP_HANDLE = bs; } - + public final static int MAX_INDY_STRING_CONCAT_ARGS = 200; - + public final static Type STRING_TYPE = Type.getType(String.class); public final static Type STRINGBUILDER_TYPE = Type.getType(StringBuilder.class); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java index 528da4384c8..df03dfcef02 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java @@ -67,6 +67,12 @@ public abstract class AExpression extends ANode { */ protected boolean explicit = false; + /** + * Set to true if a cast is allowed to boxed/unboxed. This is used + * for method arguments because casting may be required. + */ + protected boolean internal = false; + /** * Set to the value of the constant this expression node represents if * and only if the node represents a constant. If this is not null @@ -114,7 +120,7 @@ public abstract class AExpression extends ANode { * @return The new child node for the parent node calling this method. */ AExpression cast(final CompilerSettings settings, final Definition definition, final Variables variables) { - final Cast cast = AnalyzerCaster.getLegalCast(definition, location, actual, expected, explicit); + final Cast cast = AnalyzerCaster.getLegalCast(definition, location, actual, expected, explicit, internal); if (cast == null) { if (constant == null || this instanceof EConstant) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java index 483e82cc500..f7177613857 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java @@ -495,7 +495,7 @@ public final class EBinary extends AExpression { left.write(settings, definition, adapter); right.write(settings, definition, adapter); - adapter.writeBinaryInstruction(definition, location, actual, operation); + adapter.writeBinaryInstruction(location, actual, operation); } adapter.writeBranch(tru, fals); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java index 0b91ee406e8..a7471f07b9c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java @@ -207,8 +207,8 @@ public final class EChain extends AExpression { expression = expression.cast(settings, definition, variables); - there = AnalyzerCaster.getLegalCast(definition, location, last.after, promote, false); - back = AnalyzerCaster.getLegalCast(definition, location, promote, last.after, true); + there = AnalyzerCaster.getLegalCast(definition, location, last.after, promote, false, false); + back = AnalyzerCaster.getLegalCast(definition, location, promote, last.after, true, false); this.statement = true; this.actual = read ? last.after : definition.getType("void"); @@ -289,7 +289,7 @@ public final class EChain extends AExpression { adapter.writeCast(there); expression.write(settings, definition, adapter); - adapter.writeBinaryInstruction(definition, location, promote, operation); + adapter.writeBinaryInstruction(location, promote, operation); adapter.writeCast(back); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java index 45976c13414..69f22e828cd 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java @@ -57,8 +57,10 @@ public final class EConditional extends AExpression { left.expected = expected; left.explicit = explicit; + left.internal = internal; right.expected = expected; right.explicit = explicit; + right.internal = internal; actual = expected; left.analyze(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCall.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCall.java index bd76aa293cc..9e519714a97 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCall.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCall.java @@ -64,6 +64,7 @@ public final class LCall extends ALink { final AExpression expression = arguments.get(argument); expression.expected = method.arguments.get(argument); + expression.internal = true; expression.analyze(settings, definition, variables); arguments.set(argument, expression.cast(settings, definition, variables)); } @@ -79,7 +80,7 @@ public final class LCall extends ALink { return link.analyze(settings, definition, variables); } - throw new IllegalArgumentException(error("Unknown call [" + name + "] with [" + arguments.size() + + throw new IllegalArgumentException(error("Unknown call [" + name + "] with [" + arguments.size() + "] arguments on type [" + struct.name + "].")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java index eb7fb3a6b10..126b8b2711b 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java @@ -55,7 +55,7 @@ public final class LCast extends ALink { throw new IllegalArgumentException(error("Not a type [" + type + "].")); } - cast = AnalyzerCaster.getLegalCast(definition, location, before, after, true); + cast = AnalyzerCaster.getLegalCast(definition, location, before, after, true, false); return cast != null ? this : null; } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java index 1285d548163..1f7544d32c1 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java @@ -49,6 +49,7 @@ final class LDefCall extends ALink implements IDefLink { for (int argument = 0; argument < arguments.size(); ++argument) { final AExpression expression = arguments.get(argument); + expression.internal = true; expression.analyze(settings, definition, variables); expression.expected = expression.actual; arguments.set(argument, expression.cast(settings, definition, variables)); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java index 227b63cf31f..5610c8dd7e7 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java @@ -78,6 +78,7 @@ public final class LNewObj extends ALink { final AExpression expression = arguments.get(argument); expression.expected = types[argument]; + expression.internal = true; expression.analyze(settings, definition, variables); arguments.set(argument, expression.cast(settings, definition, variables)); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java index 39ab0c099a6..1af2e213ebc 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java @@ -50,6 +50,7 @@ public final class SExpression extends AStatement { final boolean rtn = lastSource && expression.actual.sort != Sort.VOID; expression.expected = rtn ? definition.getType("Object") : expression.actual; + expression.internal = rtn; expression = expression.cast(settings, definition, variables); methodEscape = rtn; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java index 68084a9a70c..dc76ca4c33d 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java @@ -40,6 +40,7 @@ public final class SReturn extends AStatement { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { expression.expected = definition.getType("Object"); + expression.internal = true; expression.analyze(settings, definition, variables); expression = expression.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/package-info.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/package-info.java index ab6944619ca..0d4e993b39b 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/package-info.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/package-info.java @@ -22,6 +22,7 @@ *

* The following are the types of nodes: * A* (abstract) - These are the abstract nodes that are the superclasses for the other types. + * I* (interface) -- Thse are marker interfaces to denote a property of the node. * S* (statement) - These are nodes that represent a statement in Painless. These are the highest level nodes. * E* (expression) - These are nodess that represent an expression in Painless. These are the middle level nodes. * L* (link) - These are nodes that respresent a piece of a variable/method chain. The are the lowest level nodes. diff --git a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/definition.txt b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/definition.txt index 4ca37223043..379fadb9865 100644 --- a/modules/lang-painless/src/main/resources/org/elasticsearch/painless/definition.txt +++ b/modules/lang-painless/src/main/resources/org/elasticsearch/painless/definition.txt @@ -69,7 +69,6 @@ class Void -> java.lang.Void extends Object { } class Boolean -> java.lang.Boolean extends Object { - Boolean (boolean) Boolean TRUE Boolean FALSE int compare(boolean,boolean) @@ -80,7 +79,6 @@ class Boolean -> java.lang.Boolean extends Object { } class Byte -> java.lang.Byte extends Number,Object { - Byte (byte) byte MIN_VALUE byte MAX_VALUE int compare(byte,byte) @@ -90,7 +88,6 @@ class Byte -> java.lang.Byte extends Number,Object { } class Short -> java.lang.Short extends Number,Object { - Short (short) short MIN_VALUE short MAX_VALUE int compare(short,short) @@ -100,7 +97,6 @@ class Short -> java.lang.Short extends Number,Object { } class Character -> java.lang.Character extends Object { - Character (char) char MIN_VALUE char MAX_VALUE int charCount(int) @@ -127,7 +123,6 @@ class Character -> java.lang.Character extends Object { } class Integer -> java.lang.Integer extends Number,Object { - Integer (int) int MIN_VALUE int MAX_VALUE int compare(int,int) @@ -141,7 +136,6 @@ class Integer -> java.lang.Integer extends Number,Object { } class Long -> java.lang.Long extends Number,Object { - Long (long) long MIN_VALUE long MAX_VALUE int compare(long,long) @@ -155,7 +149,6 @@ class Long -> java.lang.Long extends Number,Object { } class Float -> java.lang.Float extends Number,Object { - Float (float) float MIN_VALUE float MAX_VALUE int compare(float,float) @@ -168,7 +161,6 @@ class Float -> java.lang.Float extends Number,Object { } class Double -> java.lang.Double extends Number,Object { - Double (double) double MIN_VALUE double MAX_VALUE int compare(double,double) @@ -365,152 +357,6 @@ class GeoPoints -> org.elasticsearch.index.fielddata.ScriptDocValues$GeoPoints e double geohashDistanceInMiles(String) } -# internal conversion methods -class Utility -> org.elasticsearch.painless.Utility { - boolean NumberToboolean(Number) - char NumberTochar(Number) - Boolean NumberToBoolean(Number) - Byte NumberToByte(Number) - Short NumberToShort(Number) - Character NumberToCharacter(Number) - Integer NumberToInteger(Number) - Long NumberToLong(Number) - Float NumberToFloat(Number) - Double NumberToDouble(Number) - byte booleanTobyte(boolean) - short booleanToshort(boolean) - char booleanTochar(boolean) - int booleanToint(boolean) - long booleanTolong(boolean) - float booleanTofloat(boolean) - double booleanTodouble(boolean) - Integer booleanToInteger(boolean) - byte BooleanTobyte(Boolean) - short BooleanToshort(Boolean) - char BooleanTochar(Boolean) - int BooleanToint(Boolean) - long BooleanTolong(Boolean) - float BooleanTofloat(Boolean) - double BooleanTodouble(Boolean) - Byte BooleanToByte(Boolean) - Short BooleanToShort(Boolean) - Character BooleanToCharacter(Boolean) - Integer BooleanToInteger(Boolean) - Long BooleanToLong(Boolean) - Float BooleanToFloat(Boolean) - Double BooleanToDouble(Boolean) - boolean byteToboolean(byte) - Short byteToShort(byte) - Character byteToCharacter(byte) - Integer byteToInteger(byte) - Long byteToLong(byte) - Float byteToFloat(byte) - Double byteToDouble(byte) - boolean ByteToboolean(Byte) - char ByteTochar(Byte) - boolean shortToboolean(short) - Byte shortToByte(short) - Character shortToCharacter(short) - Integer shortToInteger(short) - Long shortToLong(short) - Float shortToFloat(short) - Double shortToDouble(short) - boolean ShortToboolean(Short) - char ShortTochar(Short) - boolean charToboolean(char) - Byte charToByte(char) - Short charToShort(char) - Integer charToInteger(char) - Long charToLong(char) - Float charToFloat(char) - Double charToDouble(char) - String charToString(char) - boolean CharacterToboolean(Character) - byte CharacterTobyte(Character) - short CharacterToshort(Character) - int CharacterToint(Character) - long CharacterTolong(Character) - float CharacterTofloat(Character) - double CharacterTodouble(Character) - Boolean CharacterToBoolean(Character) - Byte CharacterToByte(Character) - Short CharacterToShort(Character) - Integer CharacterToInteger(Character) - Long CharacterToLong(Character) - Float CharacterToFloat(Character) - Double CharacterToDouble(Character) - String CharacterToString(Character) - boolean intToboolean(int) - Byte intToByte(int) - Short intToShort(int) - Character intToCharacter(int) - Long intToLong(int) - Float intToFloat(int) - Double intToDouble(int) - boolean IntegerToboolean(Integer) - char IntegerTochar(Integer) - boolean longToboolean(long) - Byte longToByte(long) - Short longToShort(long) - Character longToCharacter(long) - Integer longToInteger(long) - Float longToFloat(long) - Double longToDouble(long) - boolean LongToboolean(Long) - char LongTochar(Long) - boolean floatToboolean(float) - Byte floatToByte(float) - Short floatToShort(float) - Character floatToCharacter(float) - Integer floatToInteger(float) - Long floatToLong(float) - Double floatToDouble(float) - boolean FloatToboolean(Float) - char FloatTochar(Float) - boolean doubleToboolean(double) - Byte doubleToByte(double) - Short doubleToShort(double) - Character doubleToCharacter(double) - Integer doubleToInteger(double) - Long doubleToLong(double) - Float doubleToFloat(double) - boolean DoubleToboolean(Double) - char DoubleTochar(Double) - char StringTochar(String) - Character StringToCharacter(String) -} - -class Def -> org.elasticsearch.painless.Def { - byte DefTobyteImplicit(def) - short DefToshortImplicit(def) - char DefTocharImplicit(def) - int DefTointImplicit(def) - long DefTolongImplicit(def) - float DefTofloatImplicit(def) - double DefTodoubleImplicit(def) - Byte DefToByteImplicit(def) - Short DefToShortImplicit(def) - Character DefToCharacterImplicit(def) - Integer DefToIntegerImplicit(def) - Long DefToLongImplicit(def) - Float DefToFloatImplicit(def) - Double DefToDoubleImplicit(def) - byte DefTobyteExplicit(def) - short DefToshortExplicit(def) - char DefTocharExplicit(def) - int DefTointExplicit(def) - long DefTolongExplicit(def) - float DefTofloatExplicit(def) - double DefTodoubleExplicit(def) - Byte DefToByteExplicit(def) - Short DefToShortExplicit(def) - Character DefToCharacterExplicit(def) - Integer DefToIntegerExplicit(def) - Long DefToLongExplicit(def) - Float DefToFloatExplicit(def) - Double DefToDoubleExplicit(def) -} - # for testing. # currently FeatureTest exposes overloaded constructor, field load store, and overloaded static methods class FeatureTest -> org.elasticsearch.painless.FeatureTest extends Object { diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicExpressionTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicExpressionTests.java index 2fb676bf299..2a8f3674ac1 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicExpressionTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicExpressionTests.java @@ -96,15 +96,15 @@ public class BasicExpressionTests extends ScriptTestCase { } /** - * Test boxed objects in various places + * Test boxed def objects in various places */ public void testBoxing() { // return assertEquals(4, exec("return params.get(\"x\");", Collections.singletonMap("x", 4))); // assignment - assertEquals(4, exec("int y = (Integer)params.get(\"x\"); return y;", Collections.singletonMap("x", 4))); + assertEquals(4, exec("int y = params.get(\"x\"); return y;", Collections.singletonMap("x", 4))); // comparison - assertEquals(true, exec("return 5 > (Integer)params.get(\"x\");", Collections.singletonMap("x", 4))); + assertEquals(true, exec("return 5 > params.get(\"x\");", Collections.singletonMap("x", 4))); } public void testBool() { diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/CompoundAssignmentTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/CompoundAssignmentTests.java index d54b976d65d..03593116538 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/CompoundAssignmentTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/CompoundAssignmentTests.java @@ -230,18 +230,18 @@ public class CompoundAssignmentTests extends ScriptTestCase { assertEquals(false, exec("boolean x = true; x &= false; return x;")); assertEquals(false, exec("boolean x = false; x &= true; return x;")); assertEquals(false, exec("boolean x = false; x &= false; return x;")); - assertEquals(true, exec("Boolean x = true; x &= true; return x;")); - assertEquals(false, exec("Boolean x = true; x &= false; return x;")); - assertEquals(false, exec("Boolean x = false; x &= true; return x;")); - assertEquals(false, exec("Boolean x = false; x &= false; return x;")); + assertEquals(true, exec("def x = true; x &= true; return x;")); + assertEquals(false, exec("def x = true; x &= false; return x;")); + assertEquals(false, exec("def x = false; x &= true; return x;")); + assertEquals(false, exec("def x = false; x &= false; return x;")); assertEquals(true, exec("boolean[] x = new boolean[1]; x[0] = true; x[0] &= true; return x[0];")); assertEquals(false, exec("boolean[] x = new boolean[1]; x[0] = true; x[0] &= false; return x[0];")); assertEquals(false, exec("boolean[] x = new boolean[1]; x[0] = false; x[0] &= true; return x[0];")); assertEquals(false, exec("boolean[] x = new boolean[1]; x[0] = false; x[0] &= false; return x[0];")); - assertEquals(true, exec("Boolean[] x = new Boolean[1]; x[0] = true; x[0] &= true; return x[0];")); - assertEquals(false, exec("Boolean[] x = new Boolean[1]; x[0] = true; x[0] &= false; return x[0];")); - assertEquals(false, exec("Boolean[] x = new Boolean[1]; x[0] = false; x[0] &= true; return x[0];")); - assertEquals(false, exec("Boolean[] x = new Boolean[1]; x[0] = false; x[0] &= false; return x[0];")); + assertEquals(true, exec("def[] x = new def[1]; x[0] = true; x[0] &= true; return x[0];")); + assertEquals(false, exec("def[] x = new def[1]; x[0] = true; x[0] &= false; return x[0];")); + assertEquals(false, exec("def[] x = new def[1]; x[0] = false; x[0] &= true; return x[0];")); + assertEquals(false, exec("def[] x = new def[1]; x[0] = false; x[0] &= false; return x[0];")); // byte assertEquals((byte) (13 & 14), exec("byte x = 13; x &= 14; return x;")); @@ -261,18 +261,18 @@ public class CompoundAssignmentTests extends ScriptTestCase { assertEquals(true, exec("boolean x = true; x |= false; return x;")); assertEquals(true, exec("boolean x = false; x |= true; return x;")); assertEquals(false, exec("boolean x = false; x |= false; return x;")); - assertEquals(true, exec("Boolean x = true; x |= true; return x;")); - assertEquals(true, exec("Boolean x = true; x |= false; return x;")); - assertEquals(true, exec("Boolean x = false; x |= true; return x;")); - assertEquals(false, exec("Boolean x = false; x |= false; return x;")); + assertEquals(true, exec("def x = true; x |= true; return x;")); + assertEquals(true, exec("def x = true; x |= false; return x;")); + assertEquals(true, exec("def x = false; x |= true; return x;")); + assertEquals(false, exec("def x = false; x |= false; return x;")); assertEquals(true, exec("boolean[] x = new boolean[1]; x[0] = true; x[0] |= true; return x[0];")); assertEquals(true, exec("boolean[] x = new boolean[1]; x[0] = true; x[0] |= false; return x[0];")); assertEquals(true, exec("boolean[] x = new boolean[1]; x[0] = false; x[0] |= true; return x[0];")); assertEquals(false, exec("boolean[] x = new boolean[1]; x[0] = false; x[0] |= false; return x[0];")); - assertEquals(true, exec("Boolean[] x = new Boolean[1]; x[0] = true; x[0] |= true; return x[0];")); - assertEquals(true, exec("Boolean[] x = new Boolean[1]; x[0] = true; x[0] |= false; return x[0];")); - assertEquals(true, exec("Boolean[] x = new Boolean[1]; x[0] = false; x[0] |= true; return x[0];")); - assertEquals(false, exec("Boolean[] x = new Boolean[1]; x[0] = false; x[0] |= false; return x[0];")); + assertEquals(true, exec("def[] x = new def[1]; x[0] = true; x[0] |= true; return x[0];")); + assertEquals(true, exec("def[] x = new def[1]; x[0] = true; x[0] |= false; return x[0];")); + assertEquals(true, exec("def[] x = new def[1]; x[0] = false; x[0] |= true; return x[0];")); + assertEquals(false, exec("def[] x = new def[1]; x[0] = false; x[0] |= false; return x[0];")); // byte assertEquals((byte) (13 | 14), exec("byte x = 13; x |= 14; return x;")); @@ -292,18 +292,18 @@ public class CompoundAssignmentTests extends ScriptTestCase { assertEquals(true, exec("boolean x = true; x ^= false; return x;")); assertEquals(true, exec("boolean x = false; x ^= true; return x;")); assertEquals(false, exec("boolean x = false; x ^= false; return x;")); - assertEquals(false, exec("Boolean x = true; x ^= true; return x;")); - assertEquals(true, exec("Boolean x = true; x ^= false; return x;")); - assertEquals(true, exec("Boolean x = false; x ^= true; return x;")); - assertEquals(false, exec("Boolean x = false; x ^= false; return x;")); + assertEquals(false, exec("def x = true; x ^= true; return x;")); + assertEquals(true, exec("def x = true; x ^= false; return x;")); + assertEquals(true, exec("def x = false; x ^= true; return x;")); + assertEquals(false, exec("def x = false; x ^= false; return x;")); assertEquals(false, exec("boolean[] x = new boolean[1]; x[0] = true; x[0] ^= true; return x[0];")); assertEquals(true, exec("boolean[] x = new boolean[1]; x[0] = true; x[0] ^= false; return x[0];")); assertEquals(true, exec("boolean[] x = new boolean[1]; x[0] = false; x[0] ^= true; return x[0];")); assertEquals(false, exec("boolean[] x = new boolean[1]; x[0] = false; x[0] ^= false; return x[0];")); - assertEquals(false, exec("Boolean[] x = new Boolean[1]; x[0] = true; x[0] ^= true; return x[0];")); - assertEquals(true, exec("Boolean[] x = new Boolean[1]; x[0] = true; x[0] ^= false; return x[0];")); - assertEquals(true, exec("Boolean[] x = new Boolean[1]; x[0] = false; x[0] ^= true; return x[0];")); - assertEquals(false, exec("Boolean[] x = new Boolean[1]; x[0] = false; x[0] ^= false; return x[0];")); + assertEquals(false, exec("def[] x = new def[1]; x[0] = true; x[0] ^= true; return x[0];")); + assertEquals(true, exec("def[] x = new def[1]; x[0] = true; x[0] ^= false; return x[0];")); + assertEquals(true, exec("def[] x = new def[1]; x[0] = false; x[0] ^= true; return x[0];")); + assertEquals(false, exec("def[] x = new def[1]; x[0] = false; x[0] ^= false; return x[0];")); // byte assertEquals((byte) (13 ^ 14), exec("byte x = 13; x ^= 14; return x;")); diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ConditionalTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ConditionalTests.java index 859825f129a..bfcadef3b84 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ConditionalTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ConditionalTests.java @@ -65,9 +65,6 @@ public class ConditionalTests extends ScriptTestCase { public void testPromotion() { assertEquals(false, exec("boolean x = false; boolean y = true; return (x ? 2 : 4.0F) == (y ? 2 : 4.0F);")); - assertEquals(false, exec("boolean x = false; boolean y = true; return (x ? 2 : 4.0F) == (y ? new Long(2) : new Float(4.0F));")); - assertEquals(false, exec("boolean x = false; boolean y = true; " + - "return (x ? new HashMap() : new ArrayList()) == (y ? new Long(2) : new Float(4.0F));")); assertEquals(false, exec("boolean x = false; boolean y = true; return (x ? 2 : 4.0F) == (y ? new HashMap() : new ArrayList());")); } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java index 8043d9da915..bf7d41dfa62 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java @@ -94,7 +94,7 @@ public class EqualsTests extends ScriptTestCase { } public void testEquals() { - assertEquals(true, exec("return new Long(3) == new Long(3);")); + assertEquals(true, exec("return Long.valueOf(3) == 3L;")); assertEquals(false, exec("return new Long(3) === new Long(3);")); assertEquals(true, exec("Integer x = new Integer(3); Object y = x; return x == y;")); assertEquals(true, exec("Integer x = new Integer(3); Object y = x; return x === y;")); @@ -143,11 +143,11 @@ public class EqualsTests extends ScriptTestCase { public void testBranchNotEquals() { assertEquals(1, exec("Character a = (char)'a'; Character b = (char)'b'; if (a != b) return 1; else return 0;")); assertEquals(0, exec("Character a = (char)'a'; Character b = (char)'a'; if (a != b) return 1; else return 0;")); - assertEquals(1, exec("Integer a = new Integer(1); Integer b = 1; if (a !== b) return 1; else return 0;")); - assertEquals(1, exec("Character a = (char)'a'; Character b = new Character((char)'a'); if (a !== b) return 1; else return 0;")); - assertEquals(0, exec("Character a = (char)'a'; Object b = a; if (a !== b) return 1; else return 0;")); - assertEquals(0, exec("Integer a = 1; Number b = a; Number c = a; if (c !== b) return 1; else return 0;")); - assertEquals(1, exec("Integer a = 1; Character b = (char)'a'; if (a !== (Object)b) return 1; else return 0;")); + assertEquals(1, exec("def a = 1; def b = 1; if (a !== b) return 1; else return 0;")); + assertEquals(1, exec("def a = (char)'a'; Character b = new Character((char)'a'); if (a !== b) return 1; else return 0;")); + assertEquals(0, exec("def a = (char)'a'; Object b = a; if (a !== b) return 1; else return 0;")); + assertEquals(0, exec("def a = 1; Number b = a; Number c = a; if (c !== b) return 1; else return 0;")); + assertEquals(1, exec("def a = 1; Character b = (char)'a'; if (a !== (Object)b) return 1; else return 0;")); } public void testRightHandNull() { diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java index e61541bf371..5cd3c64925c 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java @@ -70,13 +70,13 @@ public class StringTests extends ScriptTestCase { public void testAppendMultiple() { assertEquals("cat" + true + "abc" + null, exec("String s = \"cat\"; return s + true + 'abc' + null;")); } - + public void testAppendMany() { for (int i = MAX_INDY_STRING_CONCAT_ARGS - 5; i < MAX_INDY_STRING_CONCAT_ARGS + 5; i++) { doTestAppendMany(i); } } - + private void doTestAppendMany(int count) { StringBuilder script = new StringBuilder("String s = \"cat\"; return s"); StringBuilder result = new StringBuilder("cat"); @@ -90,11 +90,11 @@ public class StringTests extends ScriptTestCase { Debugger.toString(s).contains(String.format(Locale.ROOT, "LDC \"%03d\"", count/2))); assertEquals(result.toString(), exec(s)); } - + public void testNestedConcats() { assertEquals("foo1010foo", exec("String s = 'foo'; String x = '10'; return s + Integer.parseInt(x + x) + s;")); } - + public void testStringAPI() { assertEquals("", exec("return new String();")); assertEquals('x', exec("String s = \"x\"; return s.charAt(0);")); @@ -189,41 +189,5 @@ public class StringTests extends ScriptTestCase { } catch (final ClassCastException cce) { assertTrue(cce.getMessage().contains("Cannot cast [String] with length greater than one to [char].")); } - - assertEquals('c', exec("return (Character)\"c\"")); - assertEquals('c', exec("return (Character)'c'")); - assertEquals("c", exec("return (String)(Character)\"c\"")); - assertEquals("c", exec("return (String)(Character)'c'")); - - assertEquals('c', exec("String s = \"c\"; (Character)s")); - assertEquals('c', exec("String s = 'c'; (Character)s")); - - try { - assertEquals("cc", exec("return (String)(Character)\"cc\"")); - fail(); - } catch (final ClassCastException ise) { - assertTrue(ise.getMessage().contains("Cannot cast [String] with length greater than one to [Character].")); - } - - try { - assertEquals("cc", exec("return (String)(Character)'cc'")); - fail(); - } catch (final ClassCastException ise) { - assertTrue(ise.getMessage().contains("Cannot cast [String] with length greater than one to [Character].")); - } - - try { - assertEquals('c', exec("String s = \"cc\"; (Character)s")); - fail(); - } catch (final ClassCastException cce) { - assertTrue(cce.getMessage().contains("Cannot cast [String] with length greater than one to [Character].")); - } - - try { - assertEquals('c', exec("String s = 'cc'; (Character)s")); - fail(); - } catch (final ClassCastException cce) { - assertTrue(cce.getMessage().contains("Cannot cast [String] with length greater than one to [Character].")); - } } } From 82aed083016d64a7856f3e5a0d3aae52f8debbe0 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Fri, 20 May 2016 10:48:41 +0200 Subject: [PATCH 09/22] Restore constants as static final (first step) --- .../painless/AnalyzerCaster.java | 96 +++++++++---------- .../elasticsearch/painless/Definition.java | 32 ++++++- .../elasticsearch/painless/node/EBinary.java | 6 +- .../elasticsearch/painless/node/EBool.java | 6 +- .../elasticsearch/painless/node/EBoolean.java | 2 +- .../elasticsearch/painless/node/EChain.java | 6 +- .../elasticsearch/painless/node/EComp.java | 16 ++-- .../painless/node/EConditional.java | 2 +- .../painless/node/EConstant.java | 18 ++-- .../elasticsearch/painless/node/EDecimal.java | 4 +- .../elasticsearch/painless/node/ENull.java | 2 +- .../elasticsearch/painless/node/ENumeric.java | 14 +-- .../elasticsearch/painless/node/EUnary.java | 4 +- .../painless/node/LArrayLength.java | 2 +- .../elasticsearch/painless/node/LBrace.java | 2 +- .../painless/node/LDefArray.java | 6 +- .../elasticsearch/painless/node/LDefCall.java | 4 +- .../painless/node/LDefField.java | 6 +- .../painless/node/LListShortcut.java | 2 +- .../painless/node/LNewArray.java | 2 +- .../elasticsearch/painless/node/LString.java | 2 +- .../org/elasticsearch/painless/node/SDo.java | 2 +- .../painless/node/SExpression.java | 2 +- .../org/elasticsearch/painless/node/SFor.java | 2 +- .../elasticsearch/painless/node/SIfElse.java | 2 +- .../elasticsearch/painless/node/SReturn.java | 2 +- .../elasticsearch/painless/node/SThrow.java | 2 +- .../elasticsearch/painless/node/SWhile.java | 2 +- 28 files changed, 137 insertions(+), 111 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java index d6f099e47f9..608f947016f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java @@ -119,18 +119,18 @@ public final class AnalyzerCaster { final Sort sort = from.sort; if (sort == Sort.DEF) { - return definition.getType("def"); + return Definition.defType; } else if ((sort == Sort.DOUBLE || sort == Sort.DOUBLE_OBJ) && decimal) { - return primitive ? definition.getType("double") : definition.getType("Double"); + return primitive ? Definition.doubleType : Definition.doubleobjType; } else if ((sort == Sort.FLOAT || sort == Sort.FLOAT_OBJ) && decimal) { - return primitive ? definition.getType("float") : definition.getType("Float"); + return primitive ? Definition.floatType : Definition.floatobjType; } else if (sort == Sort.LONG || sort == Sort.LONG_OBJ) { - return primitive ? definition.getType("long") : definition.getType("Long"); + return primitive ? Definition.longType : Definition.longobjType; } else if (sort == Sort.INT || sort == Sort.INT_OBJ || sort == Sort.CHAR || sort == Sort.CHAR_OBJ || sort == Sort.SHORT || sort == Sort.SHORT_OBJ || sort == Sort.BYTE || sort == Sort.BYTE_OBJ) { - return primitive ? definition.getType("int") : definition.getType("Integer"); + return primitive ? Definition.intType : Definition.intobjType; } return null; @@ -142,21 +142,21 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.DEF || sort1 == Sort.DEF) { - return definition.getType("def"); + return Definition.defType; } if (decimal) { if (sort0 == Sort.DOUBLE || sort0 == Sort.DOUBLE_OBJ || sort1 == Sort.DOUBLE || sort1 == Sort.DOUBLE_OBJ) { - return primitive ? definition.getType("double") : definition.getType("Double"); + return primitive ? Definition.doubleType : Definition.doubleobjType; } else if (sort0 == Sort.FLOAT || sort0 == Sort.FLOAT_OBJ || sort1 == Sort.FLOAT || sort1 == Sort.FLOAT_OBJ) { - return primitive ? definition.getType("float") : definition.getType("Float"); + return primitive ? Definition.floatType : Definition.floatobjType; } } if (sort0 == Sort.LONG || sort0 == Sort.LONG_OBJ || sort1 == Sort.LONG || sort1 == Sort.LONG_OBJ) { - return primitive ? definition.getType("long") : definition.getType("Long"); + return primitive ? Definition.longType : Definition.longobjType; } else if (sort0 == Sort.INT || sort0 == Sort.INT_OBJ || sort1 == Sort.INT || sort1 == Sort.INT_OBJ || sort0 == Sort.CHAR || sort0 == Sort.CHAR_OBJ || @@ -165,7 +165,7 @@ public final class AnalyzerCaster { sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ || sort0 == Sort.BYTE || sort0 == Sort.BYTE_OBJ || sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { - return primitive ? definition.getType("int") : definition.getType("Integer"); + return primitive ? Definition.intType : Definition.intobjType; } return null; @@ -176,7 +176,7 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.STRING || sort1 == Sort.STRING) { - return definition.getType("String"); + return Definition.stringType; } return promoteNumeric(definition, from0, from1, true, true); @@ -187,7 +187,7 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0.bool || sort1.bool) { - return definition.getType("boolean"); + return Definition.booleanType; } return promoteNumeric(definition, from0, from1, false, true); @@ -198,20 +198,20 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.DEF || sort1 == Sort.DEF) { - return definition.getType("def"); + return Definition.defType; } final boolean primitive = sort0.primitive && sort1.primitive; if (sort0.bool && sort1.bool) { - return primitive ? definition.getType("boolean") : definition.getType("Boolean"); + return primitive ? Definition.booleanType : Definition.booleanobjType; } if (sort0.numeric && sort1.numeric) { return promoteNumeric(definition, from0, from1, true, primitive); } - return definition.getType("Object"); + return Definition.objectType; } public static Type promoteReference(final Definition definition, final Type from0, final Type from1) { @@ -219,12 +219,12 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.DEF || sort1 == Sort.DEF) { - return definition.getType("def"); + return Definition.defType; } if (sort0.primitive && sort1.primitive) { if (sort0.bool && sort1.bool) { - return definition.getType("boolean"); + return Definition.booleanType; } if (sort0.numeric && sort1.numeric) { @@ -232,7 +232,7 @@ public final class AnalyzerCaster { } } - return definition.getType("Object"); + return Definition.objectType; } public static Type promoteConditional(final Definition definition, @@ -245,48 +245,48 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.DEF || sort1 == Sort.DEF) { - return definition.getType("def"); + return Definition.defType; } final boolean primitive = sort0.primitive && sort1.primitive; if (sort0.bool && sort1.bool) { - return primitive ? definition.getType("boolean") : definition.getType("Boolean"); + return primitive ? Definition.booleanType : Definition.booleanobjType; } if (sort0.numeric && sort1.numeric) { if (sort0 == Sort.DOUBLE || sort0 == Sort.DOUBLE_OBJ || sort1 == Sort.DOUBLE || sort1 == Sort.DOUBLE_OBJ) { - return primitive ? definition.getType("double") : definition.getType("Double"); + return primitive ? Definition.doubleType : Definition.doubleobjType; } else if (sort0 == Sort.FLOAT || sort0 == Sort.FLOAT_OBJ || sort1 == Sort.FLOAT || sort1 == Sort.FLOAT_OBJ) { - return primitive ? definition.getType("float") : definition.getType("Float"); + return primitive ? Definition.floatType : Definition.floatobjType; } else if (sort0 == Sort.LONG || sort0 == Sort.LONG_OBJ || sort1 == Sort.LONG || sort1 == Sort.LONG_OBJ) { - return sort0.primitive && sort1.primitive ? definition.getType("long") : definition.getType("Long"); + return sort0.primitive && sort1.primitive ? Definition.longType : Definition.longobjType; } else { if (sort0 == Sort.BYTE || sort0 == Sort.BYTE_OBJ) { if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return primitive ? Definition.byteType : Definition.byteobjType; } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { if (const1 != null) { final short constant = (short)const1; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return primitive ? Definition.byteType : Definition.byteobjType; } } - return primitive ? definition.getType("short") : definition.getType("Short"); + return primitive ? Definition.shortType : Definition.shortobjType; } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { - return primitive ? definition.getType("int") : definition.getType("Integer"); + return primitive ? Definition.intType : Definition.intobjType; } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { if (const1 != null) { final int constant = (int)const1; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return primitive ? Definition.byteType : Definition.byteobjType; } } - return primitive ? definition.getType("int") : definition.getType("Integer"); + return primitive ? Definition.intType : Definition.intobjType; } } else if (sort0 == Sort.SHORT || sort0 == Sort.SHORT_OBJ) { if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { @@ -294,43 +294,43 @@ public final class AnalyzerCaster { final short constant = (short)const0; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return primitive ? Definition.byteType : Definition.byteobjType; } } - return primitive ? definition.getType("short") : definition.getType("Short"); + return primitive ? Definition.shortType : Definition.shortobjType; } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { - return primitive ? definition.getType("short") : definition.getType("Short"); + return primitive ? Definition.shortType : Definition.shortobjType; } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { - return primitive ? definition.getType("int") : definition.getType("Integer"); + return primitive ? Definition.intType : Definition.intobjType; } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { if (const1 != null) { final int constant = (int)const1; if (constant <= Short.MAX_VALUE && constant >= Short.MIN_VALUE) { - return primitive ? definition.getType("short") : definition.getType("Short"); + return primitive ? Definition.shortType : Definition.shortobjType; } } - return primitive ? definition.getType("int") : definition.getType("Integer"); + return primitive ? Definition.intType : Definition.intobjType; } } else if (sort0 == Sort.CHAR || sort0 == Sort.CHAR_OBJ) { if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { - return primitive ? definition.getType("int") : definition.getType("Integer"); + return primitive ? Definition.intType : Definition.intobjType; } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { - return primitive ? definition.getType("int") : definition.getType("Integer"); + return primitive ? Definition.intType : Definition.intobjType; } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { - return primitive ? definition.getType("char") : definition.getType("Character"); + return primitive ? Definition.charType : Definition.charobjType; } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { if (const1 != null) { final int constant = (int)const1; if (constant <= Character.MAX_VALUE && constant >= Character.MIN_VALUE) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return primitive ? Definition.byteType : Definition.byteobjType; } } - return primitive ? definition.getType("int") : definition.getType("Integer"); + return primitive ? Definition.intType : Definition.intobjType; } } else if (sort0 == Sort.INT || sort0 == Sort.INT_OBJ) { if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { @@ -338,33 +338,33 @@ public final class AnalyzerCaster { final int constant = (int)const0; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return primitive ? Definition.byteType : Definition.byteobjType; } } - return primitive ? definition.getType("int") : definition.getType("Integer"); + return primitive ? Definition.intType : Definition.intobjType; } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { if (const0 != null) { final int constant = (int)const0; if (constant <= Short.MAX_VALUE && constant >= Short.MIN_VALUE) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return primitive ? Definition.byteType : Definition.byteobjType; } } - return primitive ? definition.getType("int") : definition.getType("Integer"); + return primitive ? Definition.intType : Definition.intobjType; } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { if (const0 != null) { final int constant = (int)const0; if (constant <= Character.MAX_VALUE && constant >= Character.MIN_VALUE) { - return primitive ? definition.getType("byte") : definition.getType("Byte"); + return primitive ? Definition.byteType : Definition.byteobjType; } } - return primitive ? definition.getType("int") : definition.getType("Integer"); + return primitive ? Definition.intType : Definition.intobjType; } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { - return primitive ? definition.getType("int") : definition.getType("Integer"); + return primitive ? Definition.intType : Definition.intobjType; } } } @@ -374,7 +374,7 @@ public final class AnalyzerCaster { // to calculate the highest upper bound for the two types and return that. // However, for now we just return objectType that may require an extra cast. - return definition.getType("Object"); + return Definition.objectType; } private AnalyzerCaster() {} diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java index bde6063cfe1..827c268793a 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java @@ -37,12 +37,38 @@ import java.util.Objects; * methods and fields during at both compile-time and runtime. */ public final class Definition { + + private static final String DEFINITION_FILE = "definition.txt"; /** * The default language API to be used with Painless. The second construction is used * to finalize all the variables, so there is no mistake of modification afterwards. */ - static Definition INSTANCE = new Definition(new Definition()); + public static final Definition INSTANCE = new Definition(new Definition()); + + /** Some native types as constants: */ + public static final Type booleanType = INSTANCE.getType("boolean"); + public static final Type objectType = INSTANCE.getType("Object"); + public static final Type defType = INSTANCE.getType("def"); + public static final Type booleanobjType = INSTANCE.getType("Boolean"); + public static final Type byteType = INSTANCE.getType("byte"); + public static final Type shortType = INSTANCE.getType("short"); + public static final Type intType = INSTANCE.getType("int"); + public static final Type charType = INSTANCE.getType("char"); + public static final Type longType = INSTANCE.getType("long"); + public static final Type floatType = INSTANCE.getType("float"); + public static final Type doubleType = INSTANCE.getType("double"); + public static final Type numberType = INSTANCE.getType("Number"); + public static final Type byteobjType = INSTANCE.getType("Byte"); + public static final Type shortobjType = INSTANCE.getType("Short"); + public static final Type charobjType = INSTANCE.getType("Character"); + public static final Type intobjType = INSTANCE.getType("Integer"); + public static final Type longobjType = INSTANCE.getType("Long"); + public static final Type floatobjType = INSTANCE.getType("Float"); + public static final Type doubleobjType = INSTANCE.getType("Double"); + public static final Type stringType = INSTANCE.getType("String"); + public static final Type exceptionType = INSTANCE.getType("Exception"); + public static final Type voidType = INSTANCE.getType("void"); public enum Sort { VOID( void.class , 0 , true , false , false , false ), @@ -411,7 +437,7 @@ public final class Definition { final Map> hierarchy = new HashMap<>(); int currentLine = -1; try { - try (InputStream stream = Definition.class.getResourceAsStream("definition.txt"); + try (InputStream stream = Definition.class.getResourceAsStream(DEFINITION_FILE); LineNumberReader reader = new LineNumberReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { String line = null; while ((line = reader.readLine()) != null) { @@ -477,7 +503,7 @@ public final class Definition { private void addElements() { int currentLine = -1; try { - try (InputStream stream = Definition.class.getResourceAsStream("definition.txt"); + try (InputStream stream = Definition.class.getResourceAsStream(DEFINITION_FILE); LineNumberReader reader = new LineNumberReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { String line = null; String currentClass = null; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java index f22b7394ca0..92ccf60a200 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java @@ -284,7 +284,7 @@ public final class EBinary extends AExpression { } left.expected = promote; - right.expected = definition.getType("int"); + right.expected = Definition.intType; right.explicit = true; left = left.cast(settings, definition, variables); @@ -317,7 +317,7 @@ public final class EBinary extends AExpression { } left.expected = promote; - right.expected = definition.getType("int"); + right.expected = Definition.intType; right.explicit = true; left = left.cast(settings, definition, variables); @@ -350,7 +350,7 @@ public final class EBinary extends AExpression { } left.expected = promote; - right.expected = definition.getType("int"); + right.expected = Definition.intType; right.explicit = true; left = left.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java index 4a6967c5285..1cd2564b0e1 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java @@ -45,11 +45,11 @@ public final class EBool extends AExpression { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.expected = definition.getType("boolean"); + left.expected = Definition.booleanType; left.analyze(settings, definition, variables); left = left.cast(settings, definition, variables); - right.expected = definition.getType("boolean"); + right.expected = Definition.booleanType; right.analyze(settings, definition, variables); right = right.cast(settings, definition, variables); @@ -63,7 +63,7 @@ public final class EBool extends AExpression { } } - actual = definition.getType("boolean"); + actual = Definition.booleanType; } @Override diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java index 631b47db5d1..24f1ac899e8 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java @@ -37,7 +37,7 @@ public final class EBoolean extends AExpression { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - actual = definition.getType("boolean"); + actual = Definition.booleanType; } @Override diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java index 933295f9beb..a3c0c656fda 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java @@ -199,7 +199,7 @@ public final class EChain extends AExpression { expression.expected = expression.actual; } else if (operation == Operation.LSH || operation == Operation.RSH || operation == Operation.USH) { - expression.expected = definition.getType("int"); + expression.expected = Definition.intType; expression.explicit = true; } else { expression.expected = promote; @@ -211,7 +211,7 @@ public final class EChain extends AExpression { back = AnalyzerCaster.getLegalCast(definition, location, promote, last.after, true); this.statement = true; - this.actual = read ? last.after : definition.getType("void"); + this.actual = read ? last.after : Definition.voidType; } private void analyzeWrite(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -231,7 +231,7 @@ public final class EChain extends AExpression { expression = expression.cast(settings, definition, variables); this.statement = true; - this.actual = read ? last.after : definition.getType("void"); + this.actual = read ? last.after : Definition.voidType; } private void analyzeRead() { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java index a65e82e02fa..0d781abf9b7 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java @@ -119,7 +119,7 @@ public final class EComp extends AExpression { } } - actual = definition.getType("boolean"); + actual = Definition.booleanType; } private void analyzeEqR(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -161,7 +161,7 @@ public final class EComp extends AExpression { } } - actual = definition.getType("boolean"); + actual = Definition.booleanType; } private void analyzeNE(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -207,7 +207,7 @@ public final class EComp extends AExpression { } } - actual = definition.getType("boolean"); + actual = Definition.booleanType; } private void analyzeNER(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -249,7 +249,7 @@ public final class EComp extends AExpression { } } - actual = definition.getType("boolean"); + actual = Definition.booleanType; } private void analyzeGTE(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -285,7 +285,7 @@ public final class EComp extends AExpression { } } - actual = definition.getType("boolean"); + actual = Definition.booleanType; } private void analyzeGT(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -321,7 +321,7 @@ public final class EComp extends AExpression { } } - actual = definition.getType("boolean"); + actual = Definition.booleanType; } private void analyzeLTE(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -357,7 +357,7 @@ public final class EComp extends AExpression { } } - actual = definition.getType("boolean"); + actual = Definition.booleanType; } private void analyzeLT(final CompilerSettings settings, final Definition definition, final Variables variables) { @@ -393,7 +393,7 @@ public final class EComp extends AExpression { } } - actual = definition.getType("boolean"); + actual = Definition.booleanType; } @Override diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java index 45976c13414..c1b37dfeee0 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java @@ -47,7 +47,7 @@ public final class EConditional extends AExpression { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - condition.expected = definition.getType("boolean"); + condition.expected = Definition.booleanType; condition.analyze(settings, definition, variables); condition = condition.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java index f0ee3a8de51..cbf547a0417 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java @@ -40,23 +40,23 @@ final class EConstant extends AExpression { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { if (constant instanceof String) { - actual = definition.getType("String"); + actual = Definition.stringType; } else if (constant instanceof Double) { - actual = definition.getType("double"); + actual = Definition.doubleType; } else if (constant instanceof Float) { - actual = definition.getType("float"); + actual = Definition.floatType; } else if (constant instanceof Long) { - actual = definition.getType("long"); + actual = Definition.longType; } else if (constant instanceof Integer) { - actual = definition.getType("int"); + actual = Definition.intType; } else if (constant instanceof Character) { - actual = definition.getType("char"); + actual = Definition.charType; } else if (constant instanceof Short) { - actual = definition.getType("short"); + actual = Definition.shortType; } else if (constant instanceof Byte) { - actual = definition.getType("byte"); + actual = Definition.byteType; } else if (constant instanceof Boolean) { - actual = definition.getType("boolean"); + actual = Definition.booleanType; } else { throw new IllegalStateException(error("Illegal tree structure.")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java index 9019d370895..820c3b3926e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java @@ -42,14 +42,14 @@ 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.getType("float"); + actual = Definition.floatType; } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid float constant [" + value + "].")); } } else { try { constant = Double.parseDouble(value); - actual = definition.getType("double"); + actual = Definition.doubleType; } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid double constant [" + value + "].")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java index 7098e583c5a..3e003fefe5c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java @@ -45,7 +45,7 @@ public final class ENull extends AExpression { actual = expected; } else { - actual = definition.getType("Object"); + actual = Definition.objectType; } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java index 489334ae24e..e8cf202d91d 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java @@ -49,7 +49,7 @@ public final class ENumeric extends AExpression { try { constant = Double.parseDouble(value.substring(0, value.length() - 1)); - actual = definition.getType("double"); + actual = Definition.doubleType; } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid double constant [" + value + "].")); } @@ -60,14 +60,14 @@ public final class ENumeric extends AExpression { try { constant = Float.parseFloat(value.substring(0, value.length() - 1)); - actual = definition.getType("float"); + actual = Definition.floatType; } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("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.getType("long"); + actual = Definition.longType; } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid long constant [" + value + "].")); } @@ -78,16 +78,16 @@ public final class ENumeric extends AExpression { if (sort == Sort.BYTE && integer >= Byte.MIN_VALUE && integer <= Byte.MAX_VALUE) { constant = (byte)integer; - actual = definition.getType("byte"); + actual = Definition.byteType; } else if (sort == Sort.CHAR && integer >= Character.MIN_VALUE && integer <= Character.MAX_VALUE) { constant = (char)integer; - actual = definition.getType("char"); + actual = Definition.charType; } else if (sort == Sort.SHORT && integer >= Short.MIN_VALUE && integer <= Short.MAX_VALUE) { constant = (short)integer; - actual = definition.getType("short"); + actual = Definition.shortType; } else { constant = integer; - actual = definition.getType("int"); + actual = Definition.intType; } } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid int constant [" + value + "].")); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java index 7e52790fa50..11694c344f7 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java @@ -63,7 +63,7 @@ public final class EUnary extends AExpression { } void analyzeNot(final CompilerSettings settings, final Definition definition, final Variables variables) { - child.expected = definition.getType("boolean"); + child.expected = Definition.booleanType; child.analyze(settings, definition, variables); child = child.cast(settings, definition, variables); @@ -71,7 +71,7 @@ public final class EUnary extends AExpression { constant = !(boolean)child.constant; } - actual = definition.getType("boolean"); + actual = Definition.booleanType; } void analyzeBWNot(final CompilerSettings settings, final Definition definition, final Variables variables) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java index d41128f60bb..a8047047f93 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java @@ -46,7 +46,7 @@ public final class LArrayLength extends ALink { throw new IllegalArgumentException(error("Cannot write to read-only array field [length].")); } - after = definition.getType("int"); + after = Definition.intType; } else { throw new IllegalArgumentException(error("Illegal field access [" + value + "].")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java index 1e38161ae87..fb1b11d1d07 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java @@ -50,7 +50,7 @@ public final class LBrace extends ALink { final Sort sort = before.sort; if (sort == Sort.ARRAY) { - index.expected = definition.getType("int"); + index.expected = Definition.intType; index.analyze(settings, definition, variables); index = index.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java index 68f60ef6f8f..eae33809e70 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java @@ -47,7 +47,7 @@ final class LDefArray extends ALink implements IDefLink { index.expected = index.actual; index = index.cast(settings, definition, variables); - after = definition.getType("def"); + after = Definition.defType; return this; } @@ -59,13 +59,13 @@ final class LDefArray extends ALink implements IDefLink { @Override void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { - final String desc = Type.getMethodDescriptor(after.type, definition.getType("def").type, index.actual.type); + final String desc = Type.getMethodDescriptor(after.type, Definition.defType.type, index.actual.type); adapter.invokeDynamic("arrayLoad", desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.ARRAY_LOAD); } @Override void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { - final String desc = Type.getMethodDescriptor(definition.getType("void").type, definition.getType("def").type, + final String desc = Type.getMethodDescriptor(Definition.voidType.type, Definition.defType.type, index.actual.type, after.type); adapter.invokeDynamic("arrayStore", desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.ARRAY_STORE); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java index 1285d548163..360f78eb4fd 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java @@ -55,7 +55,7 @@ final class LDefCall extends ALink implements IDefLink { } statement = true; - after = definition.getType("def"); + after = Definition.defType; return this; } @@ -71,7 +71,7 @@ final class LDefCall extends ALink implements IDefLink { signature.append('('); // first parameter is the receiver, we never know its type: always Object - signature.append(definition.getType("def").type.getDescriptor()); + signature.append(Definition.defType.type.getDescriptor()); // TODO: remove our explicit conversions and feed more type information for return value, // it can avoid some unnecessary boxing etc. diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java index 9dbe1cc3367..af20e152c70 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java @@ -44,7 +44,7 @@ final class LDefField extends ALink implements IDefLink { @Override ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - after = definition.getType("def"); + after = Definition.defType; return this; } @@ -56,13 +56,13 @@ final class LDefField extends ALink implements IDefLink { @Override void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { - final String desc = Type.getMethodDescriptor(after.type, definition.getType("def").type); + final String desc = Type.getMethodDescriptor(after.type, Definition.defType.type); adapter.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.LOAD); } @Override void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { - final String desc = Type.getMethodDescriptor(definition.getType("void").type, definition.getType("def").type, after.type); + final String desc = Type.getMethodDescriptor(Definition.voidType.type, Definition.defType.type, after.type); adapter.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.STORE); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java index f1649f3bf37..cc20fc6dec4 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java @@ -61,7 +61,7 @@ final class LListShortcut extends ALink { } if ((load || store) && (!load || getter != null) && (!store || setter != null)) { - index.expected = definition.getType("int"); + index.expected = Definition.intType; index.analyze(settings, definition, variables); index = index.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java index acafc44ede1..ffc90990cd6 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java @@ -63,7 +63,7 @@ public final class LNewArray extends ALink { for (int argument = 0; argument < arguments.size(); ++argument) { final AExpression expression = arguments.get(argument); - expression.expected = definition.getType("int"); + expression.expected = Definition.intType; expression.analyze(settings, definition, variables); arguments.set(argument, expression.cast(settings, definition, variables)); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java index 6b91cf5e87a..91f379cce76 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java @@ -45,7 +45,7 @@ public final class LString extends ALink { throw new IllegalArgumentException(error("Must read String constant [" + string + "].")); } - after = definition.getType("String"); + after = Definition.stringType; return this; } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java index 7a79fe9c02c..99f8b634d49 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java @@ -53,7 +53,7 @@ public final class SDo extends AStatement { throw new IllegalArgumentException(error("Extraneous do while loop.")); } - condition.expected = definition.getType("boolean"); + condition.expected = Definition.booleanType; condition.analyze(settings, definition, variables); condition = condition.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java index 39ab0c099a6..2ed0d10b930 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java @@ -49,7 +49,7 @@ public final class SExpression extends AStatement { final boolean rtn = lastSource && expression.actual.sort != Sort.VOID; - expression.expected = rtn ? definition.getType("Object") : expression.actual; + expression.expected = rtn ? Definition.objectType : expression.actual; expression = expression.cast(settings, definition, variables); methodEscape = rtn; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java index 239e302c72d..ef97fbac06b 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java @@ -70,7 +70,7 @@ public final class SFor extends AStatement { if (condition != null) { - condition.expected = definition.getType("boolean"); + condition.expected = Definition.booleanType; condition.analyze(settings, definition, variables); condition = condition.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java index 89dad5a96c4..34f4a80645c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java @@ -45,7 +45,7 @@ public final class SIfElse extends AStatement { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - condition.expected = definition.getType("boolean"); + condition.expected = Definition.booleanType; condition.analyze(settings, definition, variables); condition = condition.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java index 68084a9a70c..4442e5b9ee4 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java @@ -39,7 +39,7 @@ public final class SReturn extends AStatement { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - expression.expected = definition.getType("Object"); + expression.expected = Definition.objectType; expression.analyze(settings, definition, variables); expression = expression.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java index b840fce3a83..99fb5c6a973 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java @@ -39,7 +39,7 @@ public final class SThrow extends AStatement { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - expression.expected = definition.getType("Exception"); + expression.expected = Definition.exceptionType; expression.analyze(settings, definition, variables); expression = expression.cast(settings, definition, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java index 5cabb1b0f7c..83afe469320 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java @@ -44,7 +44,7 @@ public final class SWhile extends AStatement { void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { variables.incrementScope(); - condition.expected = definition.getType("boolean"); + condition.expected = Definition.booleanType; condition.analyze(settings, definition, variables); condition = condition.cast(settings, definition, variables); From 87ab39613d5d963232b1c94b223d9cf7f03aed79 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Fri, 20 May 2016 10:56:50 +0200 Subject: [PATCH 10/22] more constants --- .../elasticsearch/painless/Definition.java | 22 +++++++++---------- .../elasticsearch/painless/MethodWriter.java | 22 +++++++++---------- .../elasticsearch/painless/node/EComp.java | 12 +++++----- .../elasticsearch/painless/node/EUnary.java | 4 ++-- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java index 827c268793a..6e38bf2b7a4 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java @@ -47,28 +47,28 @@ public final class Definition { public static final Definition INSTANCE = new Definition(new Definition()); /** Some native types as constants: */ + public static final Type voidType = INSTANCE.getType("void"); public static final Type booleanType = INSTANCE.getType("boolean"); - public static final Type objectType = INSTANCE.getType("Object"); - public static final Type defType = INSTANCE.getType("def"); public static final Type booleanobjType = INSTANCE.getType("Boolean"); public static final Type byteType = INSTANCE.getType("byte"); - public static final Type shortType = INSTANCE.getType("short"); - public static final Type intType = INSTANCE.getType("int"); - public static final Type charType = INSTANCE.getType("char"); - public static final Type longType = INSTANCE.getType("long"); - public static final Type floatType = INSTANCE.getType("float"); - public static final Type doubleType = INSTANCE.getType("double"); - public static final Type numberType = INSTANCE.getType("Number"); public static final Type byteobjType = INSTANCE.getType("Byte"); + public static final Type shortType = INSTANCE.getType("short"); public static final Type shortobjType = INSTANCE.getType("Short"); - public static final Type charobjType = INSTANCE.getType("Character"); + public static final Type intType = INSTANCE.getType("int"); public static final Type intobjType = INSTANCE.getType("Integer"); + public static final Type longType = INSTANCE.getType("long"); public static final Type longobjType = INSTANCE.getType("Long"); + public static final Type floatType = INSTANCE.getType("float"); public static final Type floatobjType = INSTANCE.getType("Float"); + public static final Type doubleType = INSTANCE.getType("double"); public static final Type doubleobjType = INSTANCE.getType("Double"); + public static final Type charType = INSTANCE.getType("char"); + public static final Type charobjType = INSTANCE.getType("Character"); + public static final Type objectType = INSTANCE.getType("Object"); + public static final Type defType = INSTANCE.getType("def"); + public static final Type defobjType = INSTANCE.getType("Def"); public static final Type stringType = INSTANCE.getType("String"); public static final Type exceptionType = INSTANCE.getType("Exception"); - public static final Type voidType = INSTANCE.getType("void"); public enum Sort { VOID( void.class , 0 , true , false , false , false ), diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java index cda8c23e3bf..ce1bb531655 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java @@ -214,17 +214,17 @@ public final class MethodWriter extends GeneratorAdapter { if (sort == Sort.DEF) { switch (operation) { - case MUL: invokeStatic(definition.getType("Def").type, DEF_MUL_CALL); break; - case DIV: invokeStatic(definition.getType("Def").type, DEF_DIV_CALL); break; - case REM: invokeStatic(definition.getType("Def").type, DEF_REM_CALL); break; - case ADD: invokeStatic(definition.getType("Def").type, DEF_ADD_CALL); break; - case SUB: invokeStatic(definition.getType("Def").type, DEF_SUB_CALL); break; - case LSH: invokeStatic(definition.getType("Def").type, DEF_LSH_CALL); break; - case USH: invokeStatic(definition.getType("Def").type, DEF_RSH_CALL); break; - case RSH: invokeStatic(definition.getType("Def").type, DEF_USH_CALL); break; - case BWAND: invokeStatic(definition.getType("Def").type, DEF_AND_CALL); break; - case XOR: invokeStatic(definition.getType("Def").type, DEF_XOR_CALL); break; - case BWOR: invokeStatic(definition.getType("Def").type, DEF_OR_CALL); break; + case MUL: invokeStatic(Definition.defobjType.type, DEF_MUL_CALL); break; + case DIV: invokeStatic(Definition.defobjType.type, DEF_DIV_CALL); break; + case REM: invokeStatic(Definition.defobjType.type, DEF_REM_CALL); break; + case ADD: invokeStatic(Definition.defobjType.type, DEF_ADD_CALL); break; + case SUB: invokeStatic(Definition.defobjType.type, DEF_SUB_CALL); break; + case LSH: invokeStatic(Definition.defobjType.type, DEF_LSH_CALL); break; + case USH: invokeStatic(Definition.defobjType.type, DEF_RSH_CALL); break; + case RSH: invokeStatic(Definition.defobjType.type, DEF_USH_CALL); break; + case BWAND: invokeStatic(Definition.defobjType.type, DEF_AND_CALL); break; + case XOR: invokeStatic(Definition.defobjType.type, DEF_XOR_CALL); break; + case BWOR: invokeStatic(Definition.defobjType.type, DEF_OR_CALL); break; default: throw new IllegalStateException("Error " + location + ": Illegal tree structure."); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java index 0d781abf9b7..9d7862e404a 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java @@ -456,7 +456,7 @@ public final class EComp extends AExpression { if (right.isNull) { adapter.ifNull(jump); } else if (!left.isNull && operation == Operation.EQ) { - adapter.invokeStatic(definition.getType("Def").type, DEF_EQ_CALL); + adapter.invokeStatic(Definition.defobjType.type, DEF_EQ_CALL); } else { adapter.ifCmp(rtype, MethodWriter.EQ, jump); } @@ -464,19 +464,19 @@ public final class EComp extends AExpression { if (right.isNull) { adapter.ifNonNull(jump); } else if (!left.isNull && operation == Operation.NE) { - adapter.invokeStatic(definition.getType("Def").type, DEF_EQ_CALL); + adapter.invokeStatic(Definition.defobjType.type, DEF_EQ_CALL); adapter.ifZCmp(MethodWriter.EQ, jump); } else { adapter.ifCmp(rtype, MethodWriter.NE, jump); } } else if (lt) { - adapter.invokeStatic(definition.getType("Def").type, DEF_LT_CALL); + adapter.invokeStatic(Definition.defobjType.type, DEF_LT_CALL); } else if (lte) { - adapter.invokeStatic(definition.getType("Def").type, DEF_LTE_CALL); + adapter.invokeStatic(Definition.defobjType.type, DEF_LTE_CALL); } else if (gt) { - adapter.invokeStatic(definition.getType("Def").type, DEF_GT_CALL); + adapter.invokeStatic(Definition.defobjType.type, DEF_GT_CALL); } else if (gte) { - adapter.invokeStatic(definition.getType("Def").type, DEF_GTE_CALL); + adapter.invokeStatic(Definition.defobjType.type, DEF_GTE_CALL); } else { throw new IllegalStateException(error("Illegal tree structure.")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java index 11694c344f7..627eb85e968 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java @@ -191,7 +191,7 @@ public final class EUnary extends AExpression { if (operation == Operation.BWNOT) { if (sort == Sort.DEF) { - adapter.invokeStatic(definition.getType("Def").type, DEF_NOT_CALL); + adapter.invokeStatic(Definition.defobjType.type, DEF_NOT_CALL); } else { if (sort == Sort.INT) { adapter.push(-1); @@ -205,7 +205,7 @@ public final class EUnary extends AExpression { } } else if (operation == Operation.SUB) { if (sort == Sort.DEF) { - adapter.invokeStatic(definition.getType("Def").type, DEF_NEG_CALL); + adapter.invokeStatic(Definition.defobjType.type, DEF_NEG_CALL); } else { adapter.math(MethodWriter.NEG, type); } From 4e454439bb3d9b9a4e949dfed98736303a584e65 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Fri, 20 May 2016 02:04:38 -0700 Subject: [PATCH 11/22] Fixed bugs in comparison with Def. Fixed may tests.n --- .../painless/AnalyzerCaster.java | 7 +- .../org/elasticsearch/painless/Utility.java | 432 ------------------ .../org/elasticsearch/painless/Writer.java | 2 +- .../painless/WriterConstants.java | 1 - .../elasticsearch/painless/node/EComp.java | 33 +- .../painless/node/EExplicit.java | 1 + .../elasticsearch/painless/node/EUnary.java | 5 +- .../elasticsearch/painless/ArrayTests.java | 18 +- .../painless/ConditionalTests.java | 3 +- .../painless/DefOperationTests.java | 8 +- .../elasticsearch/painless/EqualsTests.java | 79 +--- .../elasticsearch/painless/StringTests.java | 4 +- 12 files changed, 68 insertions(+), 525 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java index 11a334eff1d..0e490054a25 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java @@ -633,7 +633,7 @@ public final class AnalyzerCaster { case LONG: case FLOAT: case DOUBLE: - return new Cast(actual, expected, true, true, false, false, false); + return new Cast(actual, expected, explicit, true, false, false, false); } break; @@ -649,8 +649,9 @@ public final class AnalyzerCaster { break; } - if (expected.clazz.isAssignableFrom(actual.clazz) || - ((explicit || expected.sort == Sort.DEF) && actual.clazz.isAssignableFrom(expected.clazz))) { + if (actual.sort == Sort.DEF || expected.sort == Sort.DEF || + expected.clazz.isAssignableFrom(actual.clazz) || + explicit && actual.clazz.isAssignableFrom(expected.clazz)) { return new Cast(actual, expected, explicit); } else { throw new ClassCastException("Error" + location + ": Cannot cast from [" + actual.name + "] to [" + expected.name + "]."); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java index c8429f9458a..5ab3450db7e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java @@ -25,442 +25,10 @@ package org.elasticsearch.painless; */ public class Utility { - public static boolean NumberToboolean(final Number value) { - return value.longValue() != 0; - } - - public static char NumberTochar(final Number value) { - return (char)value.intValue(); - } - - public static Boolean NumberToBoolean(final Number value) { - return value.longValue() != 0; - } - - public static Byte NumberToByte(final Number value) { - return value == null ? null : value.byteValue(); - } - - public static Short NumberToShort(final Number value) { - return value == null ? null : value.shortValue(); - } - - public static Character NumberToCharacter(final Number value) { - return value == null ? null : (char)value.intValue(); - } - - public static Integer NumberToInteger(final Number value) { - return value == null ? null : value.intValue(); - } - - public static Long NumberToLong(final Number value) { - return value == null ? null : value.longValue(); - } - - public static Float NumberToFloat(final Number value) { - return value == null ? null : value.floatValue(); - } - - public static Double NumberToDouble(final Number value) { - return value == null ? null : value.doubleValue(); - } - - public static byte booleanTobyte(final boolean value) { - return (byte)(value ? 1 : 0); - } - - public static short booleanToshort(final boolean value) { - return (short)(value ? 1 : 0); - } - - public static char booleanTochar(final boolean value) { - return (char)(value ? 1 : 0); - } - - public static int booleanToint(final boolean value) { - return value ? 1 : 0; - } - - public static long booleanTolong(final boolean value) { - return value ? 1 : 0; - } - - public static float booleanTofloat(final boolean value) { - return value ? 1 : 0; - } - - public static double booleanTodouble(final boolean value) { - return value ? 1 : 0; - } - - public static Integer booleanToInteger(final boolean value) { - return value ? 1 : 0; - } - - public static byte BooleanTobyte(final Boolean value) { - return (byte)(value ? 1 : 0); - } - - public static short BooleanToshort(final Boolean value) { - return (short)(value ? 1 : 0); - } - - public static char BooleanTochar(final Boolean value) { - return (char)(value ? 1 : 0); - } - - public static int BooleanToint(final Boolean value) { - return value ? 1 : 0; - } - - public static long BooleanTolong(final Boolean value) { - return value ? 1 : 0; - } - - public static float BooleanTofloat(final Boolean value) { - return value ? 1 : 0; - } - - public static double BooleanTodouble(final Boolean value) { - return value ? 1 : 0; - } - - public static Byte BooleanToByte(final Boolean value) { - return value == null ? null : (byte)(value ? 1 : 0); - } - - public static Short BooleanToShort(final Boolean value) { - return value == null ? null : (short)(value ? 1 : 0); - } - - public static Character BooleanToCharacter(final Boolean value) { - return value == null ? null : (char)(value ? 1 : 0); - } - - public static Integer BooleanToInteger(final Boolean value) { - return value == null ? null : value ? 1 : 0; - } - - public static Long BooleanToLong(final Boolean value) { - return value == null ? null : value ? 1L : 0L; - } - - public static Float BooleanToFloat(final Boolean value) { - return value == null ? null : value ? 1F : 0F; - } - - public static Double BooleanToDouble(final Boolean value) { - return value == null ? null : value ? 1D : 0D; - } - - public static boolean byteToboolean(final byte value) { - return value != 0; - } - - public static Short byteToShort(final byte value) { - return (short)value; - } - - public static Character byteToCharacter(final byte value) { - return (char)value; - } - - public static Integer byteToInteger(final byte value) { - return (int)value; - } - - public static Long byteToLong(final byte value) { - return (long)value; - } - - public static Float byteToFloat(final byte value) { - return (float)value; - } - - public static Double byteToDouble(final byte value) { - return (double)value; - } - - public static boolean ByteToboolean(final Byte value) { - return value != 0; - } - - public static char ByteTochar(final Byte value) { - return (char)value.byteValue(); - } - - public static boolean shortToboolean(final short value) { - return value != 0; - } - - public static Byte shortToByte(final short value) { - return (byte)value; - } - - public static Character shortToCharacter(final short value) { - return (char)value; - } - - public static Integer shortToInteger(final short value) { - return (int)value; - } - - public static Long shortToLong(final short value) { - return (long)value; - } - - public static Float shortToFloat(final short value) { - return (float)value; - } - - public static Double shortToDouble(final short value) { - return (double)value; - } - - public static boolean ShortToboolean(final Short value) { - return value != 0; - } - - public static char ShortTochar(final Short value) { - return (char)value.shortValue(); - } - - public static boolean charToboolean(final char value) { - return value != 0; - } - - public static Byte charToByte(final char value) { - return (byte)value; - } - - public static Short charToShort(final char value) { - return (short)value; - } - - public static Integer charToInteger(final char value) { - return (int)value; - } - - public static Long charToLong(final char value) { - return (long)value; - } - - public static Float charToFloat(final char value) { - return (float)value; - } - - public static Double charToDouble(final char value) { - return (double)value; - } - public static String charToString(final char value) { return String.valueOf(value); } - public static boolean CharacterToboolean(final Character value) { - return value != 0; - } - - public static byte CharacterTobyte(final Character value) { - return (byte)value.charValue(); - } - - public static short CharacterToshort(final Character value) { - return (short)value.charValue(); - } - - public static int CharacterToint(final Character value) { - return value; - } - - public static long CharacterTolong(final Character value) { - return value; - } - - public static float CharacterTofloat(final Character value) { - return value; - } - - public static double CharacterTodouble(final Character value) { - return value; - } - - public static Boolean CharacterToBoolean(final Character value) { - return value == null ? null : value != 0; - } - - public static Byte CharacterToByte(final Character value) { - return value == null ? null : (byte)value.charValue(); - } - - public static Short CharacterToShort(final Character value) { - return value == null ? null : (short)value.charValue(); - } - - public static Integer CharacterToInteger(final Character value) { - return value == null ? null : (int)value; - } - - public static Long CharacterToLong(final Character value) { - return value == null ? null : (long)value; - } - - public static Float CharacterToFloat(final Character value) { - return value == null ? null : (float)value; - } - - public static Double CharacterToDouble(final Character value) { - return value == null ? null : (double)value; - } - - public static String CharacterToString(final Character value) { - return value == null ? null : value.toString(); - } - - public static boolean intToboolean(final int value) { - return value != 0; - } - - public static Byte intToByte(final int value) { - return (byte)value; - } - - public static Short intToShort(final int value) { - return (short)value; - } - - public static Character intToCharacter(final int value) { - return (char)value; - } - - public static Long intToLong(final int value) { - return (long)value; - } - - public static Float intToFloat(final int value) { - return (float)value; - } - - public static Double intToDouble(final int value) { - return (double)value; - } - - public static boolean IntegerToboolean(final Integer value) { - return value != 0; - } - - public static char IntegerTochar(final Integer value) { - return (char)value.intValue(); - } - - public static boolean longToboolean(final long value) { - return value != 0; - } - - public static Byte longToByte(final long value) { - return (byte)value; - } - - public static Short longToShort(final long value) { - return (short)value; - } - - public static Character longToCharacter(final long value) { - return (char)value; - } - - public static Integer longToInteger(final long value) { - return (int)value; - } - - public static Float longToFloat(final long value) { - return (float)value; - } - - public static Double longToDouble(final long value) { - return (double)value; - } - - public static boolean LongToboolean(final Long value) { - return value != 0; - } - - public static char LongTochar(final Long value) { - return (char)value.longValue(); - } - - public static boolean floatToboolean(final float value) { - return value != 0; - } - - public static Byte floatToByte(final float value) { - return (byte)value; - } - - public static Short floatToShort(final float value) { - return (short)value; - } - - public static Character floatToCharacter(final float value) { - return (char)value; - } - - public static Integer floatToInteger(final float value) { - return (int)value; - } - - public static Long floatToLong(final float value) { - return (long)value; - } - - public static Double floatToDouble(final float value) { - return (double)value; - } - - public static boolean FloatToboolean(final Float value) { - return value != 0; - } - - public static char FloatTochar(final Float value) { - return (char)value.floatValue(); - } - - public static boolean doubleToboolean(final double value) { - return value != 0; - } - - public static Byte doubleToByte(final double value) { - return (byte)value; - } - - public static Short doubleToShort(final double value) { - return (short)value; - } - - public static Character doubleToCharacter(final double value) { - return (char)value; - } - - public static Integer doubleToInteger(final double value) { - return (int)value; - } - - public static Long doubleToLong(final double value) { - return (long)value; - } - - public static Float doubleToFloat(final double value) { - return (float)value; - } - - public static boolean DoubleToboolean(final Double value) { - return value != 0; - } - - public static char DoubleTochar(final Double value) { - return (char)value.doubleValue(); - } - public static char StringTochar(final String value) { if (value.length() != 1) { throw new ClassCastException("Cannot cast [String] with length greater than one to [char]."); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Writer.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Writer.java index 449361867b9..d290e758ea9 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Writer.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Writer.java @@ -117,7 +117,7 @@ final class Writer { // if we truncated, make it obvious if (limit != source.length()) { fileName.append(" ..."); - } + } fileName.append(" @ "); } else { // its a named script, just use the name diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java index 6330e1603c5..e223efe36a4 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java @@ -66,7 +66,6 @@ public final class WriterConstants { new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(DefBootstrap.class), "bootstrap", DEF_BOOTSTRAP_TYPE.toMethodDescriptorString()); - public final static Type DEF_TYPE = Type.getType(Def.class); public final static Method DEF_TO_BOOLEAN = getAsmMethod(boolean.class, "DefToboolean" , Object.class); public final static Method DEF_TO_BYTE_IMPLICIT = getAsmMethod(byte.class , "DefTobyteImplicit" , Object.class); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java index 270f95e0a92..e7b610bfc92 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java @@ -35,6 +35,8 @@ import static org.elasticsearch.painless.WriterConstants.DEF_GTE_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_GT_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_LTE_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_LT_CALL; +import static org.elasticsearch.painless.WriterConstants.DEF_TYPE; +import static org.elasticsearch.painless.WriterConstants.UTILITY_TYPE; /** * Represents a comparison expression. @@ -455,34 +457,37 @@ public final class EComp extends AExpression { if (eq) { if (right.isNull) { adapter.ifNull(jump); - } else if (!left.isNull && operation == Operation.EQ) { - adapter.invokeStatic(definition.getType("Def").type, DEF_EQ_CALL); + } else if (!left.isNull && (operation == Operation.EQ || operation == Operation.NE)) { + adapter.invokeStatic(DEF_TYPE, DEF_EQ_CALL); + writejump = false; } else { adapter.ifCmp(rtype, MethodWriter.EQ, jump); } } else if (ne) { if (right.isNull) { adapter.ifNonNull(jump); - } else if (!left.isNull && operation == Operation.NE) { - adapter.invokeStatic(definition.getType("Def").type, DEF_EQ_CALL); + } else if (!left.isNull && (operation == Operation.EQ || operation == Operation.NE)) { + adapter.invokeStatic(DEF_TYPE, DEF_EQ_CALL); adapter.ifZCmp(MethodWriter.EQ, jump); } else { adapter.ifCmp(rtype, MethodWriter.NE, jump); } } else if (lt) { - adapter.invokeStatic(definition.getType("Def").type, DEF_LT_CALL); + adapter.invokeStatic(DEF_TYPE, DEF_LT_CALL); + writejump = false; } else if (lte) { - adapter.invokeStatic(definition.getType("Def").type, DEF_LTE_CALL); + adapter.invokeStatic(DEF_TYPE, DEF_LTE_CALL); + writejump = false; } else if (gt) { - adapter.invokeStatic(definition.getType("Def").type, DEF_GT_CALL); + adapter.invokeStatic(DEF_TYPE, DEF_GT_CALL); + writejump = false; } else if (gte) { - adapter.invokeStatic(definition.getType("Def").type, DEF_GTE_CALL); + adapter.invokeStatic(DEF_TYPE, DEF_GTE_CALL); + writejump = false; } else { throw new IllegalStateException(error("Illegal tree structure.")); } - writejump = left.isNull || ne || operation == Operation.EQR; - if (branch && !writejump) { adapter.ifZCmp(MethodWriter.NE, jump); } @@ -492,8 +497,8 @@ public final class EComp extends AExpression { if (eq) { if (right.isNull) { adapter.ifNull(jump); - } else if (operation == Operation.EQ) { - adapter.invokeStatic(definition.getType("Utility").type, CHECKEQUALS); + } else if (operation == Operation.EQ || operation == Operation.NE) { + adapter.invokeStatic(UTILITY_TYPE, CHECKEQUALS); if (branch) { adapter.ifZCmp(MethodWriter.NE, jump); @@ -506,8 +511,8 @@ public final class EComp extends AExpression { } else if (ne) { if (right.isNull) { adapter.ifNonNull(jump); - } else if (operation == Operation.NE) { - adapter.invokeStatic(definition.getType("Utility").type, CHECKEQUALS); + } else if (operation == Operation.EQ || operation == Operation.NE) { + adapter.invokeStatic(UTILITY_TYPE, CHECKEQUALS); adapter.ifZCmp(MethodWriter.EQ, jump); } else { adapter.ifCmp(rtype, MethodWriter.NE, jump); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java index ac0b06c0a79..d685ed9eb01 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java @@ -61,6 +61,7 @@ public final class EExplicit extends AExpression { AExpression cast(final CompilerSettings settings, final Definition definition, final Variables variables) { child.expected = expected; child.explicit = explicit; + child.internal = internal; return child.cast(settings, definition, variables); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java index 3e34c16ab97..418611ba657 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java @@ -31,6 +31,7 @@ import org.elasticsearch.painless.MethodWriter; import static org.elasticsearch.painless.WriterConstants.DEF_NEG_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_NOT_CALL; +import static org.elasticsearch.painless.WriterConstants.DEF_TYPE; /** * Represents a unary math expression. @@ -191,7 +192,7 @@ public final class EUnary extends AExpression { if (operation == Operation.BWNOT) { if (sort == Sort.DEF) { - adapter.invokeStatic(definition.getType("Def").type, DEF_NOT_CALL); + adapter.invokeStatic(DEF_TYPE, DEF_NOT_CALL); } else { if (sort == Sort.INT) { adapter.push(-1); @@ -205,7 +206,7 @@ public final class EUnary extends AExpression { } } else if (operation == Operation.SUB) { if (sort == Sort.DEF) { - adapter.invokeStatic(definition.getType("Def").type, DEF_NEG_CALL); + adapter.invokeStatic(DEF_TYPE, DEF_NEG_CALL); } else { adapter.math(MethodWriter.NEG, type); } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ArrayTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ArrayTests.java index 2036c4fd04c..8dabacdd5f9 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ArrayTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ArrayTests.java @@ -34,7 +34,7 @@ public class ArrayTests extends ScriptTestCase { assertArrayLength(10, new Integer[10]); assertArrayLength(11, new String[11][2]); } - + private void assertArrayLength(int length, Object array) throws Throwable { assertEquals(length, (int) Def.arrayLengthGetter(array.getClass()).invoke(array)); } @@ -43,36 +43,36 @@ public class ArrayTests extends ScriptTestCase { assertEquals(5, exec("def x = new int[5]; return x.length")); assertEquals(5, exec("def x = new int[4]; x[0] = 5; return x[0];")); } - + public void testArrayLoadStoreString() { assertEquals(5, exec("def x = new String[5]; return x.length")); assertEquals("foobar", exec("def x = new String[4]; x[0] = 'foobar'; return x[0];")); } - + public void testArrayLoadStoreDef() { assertEquals(5, exec("def x = new def[5]; return x.length")); assertEquals(5, exec("def x = new def[4]; x[0] = 5; return x[0];")); } - + public void testArrayCompoundInt() { assertEquals(6, exec("int[] x = new int[5]; x[0] = 5; x[0]++; return x[0];")); } - + public void testArrayCompoundDef() { assertEquals(6, exec("def x = new int[5]; x[0] = 5; x[0]++; return x[0];")); } - + public void testJacksCrazyExpression1() { assertEquals(1, exec("int x; def[] y = new def[1]; x = y[0] = 1; return x;")); } - + public void testJacksCrazyExpression2() { assertEquals(1, exec("int x; def y = new def[1]; x = y[0] = 1; return x;")); } - + public void testForLoop() { assertEquals(999*1000/2, exec("def a = new int[1000]; for (int x = 0; x < a.length; x++) { a[x] = x; } "+ "int total = 0; for (int x = 0; x < a.length; x++) { total += a[x]; } return total;")); } - + } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ConditionalTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ConditionalTests.java index bfcadef3b84..a3a09fee425 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/ConditionalTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/ConditionalTests.java @@ -65,7 +65,8 @@ public class ConditionalTests extends ScriptTestCase { public void testPromotion() { assertEquals(false, exec("boolean x = false; boolean y = true; return (x ? 2 : 4.0F) == (y ? 2 : 4.0F);")); - assertEquals(false, exec("boolean x = false; boolean y = true; return (x ? 2 : 4.0F) == (y ? new HashMap() : new ArrayList());")); + assertEquals(false, exec("boolean x = false; boolean y = true; " + + "return (x ? new HashMap() : new ArrayList()) == (y ? new HashMap() : new ArrayList());")); } public void testIncompatibleAssignment() { diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefOperationTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefOperationTests.java index 9ae657f7c1b..1b548efa3b8 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefOperationTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefOperationTests.java @@ -22,10 +22,10 @@ package org.elasticsearch.painless; public class DefOperationTests extends ScriptTestCase { public void testIllegalCast() { Exception exception = expectThrows(ClassCastException.class, () -> exec("def x = 1.0; int y = x; return y;")); - assertTrue(exception.getMessage().contains("java.lang.double cannot be cast to java.lang.int")); + assertTrue(exception.getMessage().contains("cannot be cast")); exception = expectThrows(ClassCastException.class, () -> exec("def x = (short)1; byte y = x; return y;")); - assertTrue(exception.getMessage().contains("java.lang.short cannot be cast to java.lang.byte")); + assertTrue(exception.getMessage().contains("cannot be cast")); } public void testNot() { @@ -799,7 +799,7 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(false, exec("def x = (byte)7; def y = (int)7; return x === y")); assertEquals(false, exec("def x = (short)6; def y = (int)6; return x === y")); assertEquals(false, exec("def x = (char)5; def y = (int)5; return x === y")); - assertEquals(true, exec("def x = (int)4; def y = (int)4; return x === y")); + assertEquals(false, exec("def x = (int)4; def y = (int)4; return x === y")); assertEquals(false, exec("def x = (long)5; def y = (int)3; return x === y")); assertEquals(false, exec("def x = (float)6; def y = (int)2; return x === y")); assertEquals(false, exec("def x = (double)7; def y = (int)1; return x === y")); @@ -837,7 +837,7 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(true, exec("def x = (byte)7; def y = (int)7; return x !== y")); assertEquals(true, exec("def x = (short)6; def y = (int)6; return x !== y")); assertEquals(true, exec("def x = (char)5; def y = (int)5; return x !== y")); - assertEquals(false, exec("def x = (int)4; def y = (int)4; return x !== y")); + assertEquals(true, exec("def x = (int)4; def y = (int)4; return x !== y")); assertEquals(true, exec("def x = (long)5; def y = (int)3; return x !== y")); assertEquals(true, exec("def x = (float)6; def y = (int)2; return x !== y")); assertEquals(true, exec("def x = (double)7; def y = (int)1; return x !== y")); diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java index bf7d41dfa62..59f9aadc6aa 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java @@ -94,17 +94,8 @@ public class EqualsTests extends ScriptTestCase { } public void testEquals() { - assertEquals(true, exec("return Long.valueOf(3) == 3L;")); - assertEquals(false, exec("return new Long(3) === new Long(3);")); - assertEquals(true, exec("Integer x = new Integer(3); Object y = x; return x == y;")); - assertEquals(true, exec("Integer x = new Integer(3); Object y = x; return x === y;")); - assertEquals(true, exec("Integer x = new Integer(3); Object y = new Integer(3); return x == y;")); - assertEquals(false, exec("Integer x = new Integer(3); Object y = new Integer(3); return x === y;")); - assertEquals(true, exec("Integer x = new Integer(3); int y = 3; return x == y;")); - assertEquals(true, exec("Integer x = new Integer(3); short y = 3; return x == y;")); - assertEquals(true, exec("Integer x = new Integer(3); Short y = (short)3; return x == y;")); - assertEquals(false, exec("Integer x = new Integer(3); int y = 3; return x === y;")); - assertEquals(false, exec("Integer x = new Integer(3); double y = 3; return x === y;")); + assertEquals(true, exec("return 3 == 3;")); + assertEquals(false, exec("int x = 4; int y = 5; x == y")); assertEquals(true, exec("int[] x = new int[1]; Object y = x; return x == y;")); assertEquals(true, exec("int[] x = new int[1]; Object y = x; return x === y;")); assertEquals(false, exec("int[] x = new int[1]; Object y = new int[1]; return x == y;")); @@ -114,14 +105,8 @@ public class EqualsTests extends ScriptTestCase { } public void testNotEquals() { - assertEquals(false, exec("return new Long(3) != new Long(3);")); - assertEquals(true, exec("return new Long(3) !== new Long(3);")); - assertEquals(false, exec("Integer x = new Integer(3); Object y = x; return x != y;")); - assertEquals(false, exec("Integer x = new Integer(3); Object y = x; return x !== y;")); - assertEquals(false, exec("Integer x = new Integer(3); Object y = new Integer(3); return x != y;")); - assertEquals(true, exec("Integer x = new Integer(3); Object y = new Integer(3); return x !== y;")); - assertEquals(true, exec("Integer x = new Integer(3); int y = 3; return x !== y;")); - assertEquals(true, exec("Integer x = new Integer(3); double y = 3; return x !== y;")); + assertEquals(false, exec("return 3 != 3;")); + assertEquals(true, exec("int x = 4; int y = 5; x != y")); assertEquals(false, exec("int[] x = new int[1]; Object y = x; return x != y;")); assertEquals(false, exec("int[] x = new int[1]; Object y = x; return x !== y;")); assertEquals(true, exec("int[] x = new int[1]; Object y = new int[1]; return x != y;")); @@ -131,54 +116,36 @@ public class EqualsTests extends ScriptTestCase { } public void testBranchEquals() { - assertEquals(0, exec("Character a = (char)'a'; Character b = (char)'b'; if (a == b) return 1; else return 0;")); - assertEquals(1, exec("Character a = (char)'a'; Character b = (char)'a'; if (a == b) return 1; else return 0;")); - assertEquals(0, exec("Integer a = new Integer(1); Integer b = 1; if (a === b) return 1; else return 0;")); - assertEquals(0, exec("Character a = (char)'a'; Character b = new Character((char)'a'); if (a === b) return 1; else return 0;")); - assertEquals(1, exec("Character a = (char)'a'; Object b = a; if (a === b) return 1; else return 0;")); - assertEquals(1, exec("Integer a = 1; Number b = a; Number c = a; if (c === b) return 1; else return 0;")); - assertEquals(0, exec("Integer a = 1; Character b = (char)'a'; if (a === (Object)b) return 1; else return 0;")); + assertEquals(0, exec("def a = (char)'a'; def b = (char)'b'; if (a == b) return 1; else return 0;")); + assertEquals(1, exec("def a = (char)'a'; def b = (char)'a'; if (a == b) return 1; else return 0;")); + assertEquals(0, exec("def a = 1; def b = 1; if (a === b) return 1; else return 0;")); + assertEquals(0, exec("def a = (char)'a'; def b = (char)'a'; if (a === b) return 1; else return 0;")); + assertEquals(1, exec("def a = (char)'a'; Object b = a; if (a === b) return 1; else return 0;")); + assertEquals(1, exec("def a = 1; Number b = a; Number c = a; if (c === b) return 1; else return 0;")); + assertEquals(0, exec("def a = 1; Object b = new HashMap(); if (a === (Object)b) return 1; else return 0;")); } public void testBranchNotEquals() { - assertEquals(1, exec("Character a = (char)'a'; Character b = (char)'b'; if (a != b) return 1; else return 0;")); - assertEquals(0, exec("Character a = (char)'a'; Character b = (char)'a'; if (a != b) return 1; else return 0;")); + assertEquals(1, exec("def a = (char)'a'; def b = (char)'b'; if (a != b) return 1; else return 0;")); + assertEquals(0, exec("def a = (char)'a'; def b = (char)'a'; if (a != b) return 1; else return 0;")); assertEquals(1, exec("def a = 1; def b = 1; if (a !== b) return 1; else return 0;")); - assertEquals(1, exec("def a = (char)'a'; Character b = new Character((char)'a'); if (a !== b) return 1; else return 0;")); + assertEquals(1, exec("def a = (char)'a'; def b = (char)'a'; if (a !== b) return 1; else return 0;")); assertEquals(0, exec("def a = (char)'a'; Object b = a; if (a !== b) return 1; else return 0;")); assertEquals(0, exec("def a = 1; Number b = a; Number c = a; if (c !== b) return 1; else return 0;")); - assertEquals(1, exec("def a = 1; Character b = (char)'a'; if (a !== (Object)b) return 1; else return 0;")); + assertEquals(1, exec("def a = 1; Object b = new HashMap(); if (a !== (Object)b) return 1; else return 0;")); } public void testRightHandNull() { - assertEquals(false, exec("Character a = (char)'a'; return a == null;")); - assertEquals(false, exec("Character a = (char)'a'; return a === null;")); - assertEquals(true, exec("Character a = (char)'a'; return a != null;")); - assertEquals(true, exec("Character a = (char)'a'; return a !== null;")); - assertEquals(true, exec("Character a = null; return a == null;")); - assertEquals(false, exec("Character a = null; return a != null;")); - assertEquals(false, exec("Character a = (char)'a'; Character b = null; return a == b;")); - assertEquals(true, exec("Character a = null; Character b = null; return a === b;")); - assertEquals(true, exec("Character a = (char)'a'; Character b = null; return a != b;")); - assertEquals(false, exec("Character a = null; Character b = null; return a !== b;")); - assertEquals(false, exec("Integer x = null; double y = 2.0; return x == y;")); - assertEquals(true, exec("Integer x = null; Short y = null; return x == y;")); + assertEquals(false, exec("HashMap a = new HashMap(); return a == null;")); + assertEquals(false, exec("HashMap a = new HashMap(); return a === null;")); + assertEquals(true, exec("HashMap a = new HashMap(); return a != null;")); + assertEquals(true, exec("HashMap a = new HashMap(); return a !== null;")); } public void testLeftHandNull() { - assertEquals(false, exec("Character a = (char)'a'; return null == a;")); - assertEquals(false, exec("Character a = (char)'a'; return null === a;")); - assertEquals(true, exec("Character a = (char)'a'; return null != a;")); - assertEquals(true, exec("Character a = (char)'a'; return null !== a;")); - assertEquals(true, exec("Character a = null; return null == a;")); - assertEquals(false, exec("Character a = null; return null != a;")); - assertEquals(false, exec("Character a = null; Character b = (char)'a'; return a == b;")); - assertEquals(true, exec("Character a = null; Character b = null; return a == b;")); - assertEquals(true, exec("Character a = null; Character b = null; return b === a;")); - assertEquals(true, exec("Character a = null; Character b = (char)'a'; return a != b;")); - assertEquals(false, exec("Character a = null; Character b = null; return b != a;")); - assertEquals(false, exec("Character a = null; Character b = null; return b !== a;")); - assertEquals(false, exec("Integer x = null; double y = 2.0; return y == x;")); - assertEquals(true, exec("Integer x = null; Short y = null; return y == x;")); + assertEquals(false, exec("HashMap a = new HashMap(); return null == a;")); + assertEquals(false, exec("HashMap a = new HashMap(); return null === a;")); + assertEquals(true, exec("HashMap a = new HashMap(); return null != a;")); + assertEquals(true, exec("HashMap a = new HashMap(); return null !== a;")); } } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java index 5cd3c64925c..b06199cf903 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/StringTests.java @@ -166,14 +166,14 @@ public class StringTests extends ScriptTestCase { assertEquals("cc", exec("return (String)(char)\"cc\"")); fail(); } catch (final ClassCastException cce) { - assertTrue(cce.getMessage().contains("Cannot cast from [String] to [char].")); + assertTrue(cce.getMessage().contains("Cannot cast [String] with length greater than one to [char].")); } try { assertEquals("cc", exec("return (String)(char)'cc'")); fail(); } catch (final ClassCastException cce) { - assertTrue(cce.getMessage().contains("Cannot cast from [String] to [char].")); + assertTrue(cce.getMessage().contains("Cannot cast [String] with length greater than one to [char].")); } try { From f5fc60ac678432fded7cd64548dbb9dc4bb01d52 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Fri, 20 May 2016 11:05:40 +0200 Subject: [PATCH 12/22] Add utility type constant --- .../src/main/java/org/elasticsearch/painless/Definition.java | 1 + .../src/main/java/org/elasticsearch/painless/node/EComp.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java index 6e38bf2b7a4..8013361dd9b 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java @@ -69,6 +69,7 @@ public final class Definition { public static final Type defobjType = INSTANCE.getType("Def"); public static final Type stringType = INSTANCE.getType("String"); public static final Type exceptionType = INSTANCE.getType("Exception"); + public static final Type utilityType = INSTANCE.getType("Utility"); public enum Sort { VOID( void.class , 0 , true , false , false , false ), diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java index 9d7862e404a..82033124e1c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java @@ -493,7 +493,7 @@ public final class EComp extends AExpression { if (right.isNull) { adapter.ifNull(jump); } else if (operation == Operation.EQ) { - adapter.invokeStatic(definition.getType("Utility").type, CHECKEQUALS); + adapter.invokeStatic(Definition.utilityType.type, CHECKEQUALS); if (branch) { adapter.ifZCmp(MethodWriter.NE, jump); @@ -507,7 +507,7 @@ public final class EComp extends AExpression { if (right.isNull) { adapter.ifNonNull(jump); } else if (operation == Operation.NE) { - adapter.invokeStatic(definition.getType("Utility").type, CHECKEQUALS); + adapter.invokeStatic(Definition.utilityType.type, CHECKEQUALS); adapter.ifZCmp(MethodWriter.EQ, jump); } else { adapter.ifCmp(rtype, MethodWriter.NE, jump); From 91f4bba04275223c0205b27bb8b447a158f4a346 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Fri, 20 May 2016 11:22:03 +0200 Subject: [PATCH 13/22] Make Definition's public API completely static. TODO: Remove Definition arguments everywhere and hide INSTANCE field! --- .../painless/AnalyzerCaster.java | 4 +- .../java/org/elasticsearch/painless/Def.java | 12 +- .../elasticsearch/painless/Definition.java | 125 ++++++++++-------- .../org/elasticsearch/painless/Variables.java | 4 +- .../painless/node/EExplicit.java | 2 +- .../elasticsearch/painless/node/LBrace.java | 2 +- .../elasticsearch/painless/node/LCast.java | 2 +- .../painless/node/LNewArray.java | 6 +- .../elasticsearch/painless/node/LNewObj.java | 2 +- .../painless/node/LVariable.java | 2 +- 10 files changed, 91 insertions(+), 70 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java index 608f947016f..bff486a60c5 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java @@ -41,10 +41,10 @@ public final class AnalyzerCaster { return null; } - Cast transform = definition.transformsMap.get(cast); + Cast transform = Definition.getTransform(cast); if (transform == null && explicit) { - transform = definition.transformsMap.get(new Cast(actual, expected, false)); + transform = Definition.getTransform(new Cast(actual, expected, false)); } if (transform != null) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java index 889328e58db..de9e1c43bea 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java @@ -145,7 +145,7 @@ public final class Def { Definition.MethodKey key = new Definition.MethodKey(name, type.parameterCount()); // check whitelist for matching method for (Class clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) { - RuntimeClass struct = definition.runtimeMap.get(clazz); + RuntimeClass struct = Definition.getRuntimeClass(clazz); if (struct != null) { Method method = struct.methods.get(key); @@ -155,7 +155,7 @@ public final class Def { } for (final Class iface : clazz.getInterfaces()) { - struct = definition.runtimeMap.get(iface); + struct = Definition.getRuntimeClass(iface); if (struct != null) { Method method = struct.methods.get(key); @@ -200,7 +200,7 @@ public final class Def { static MethodHandle lookupGetter(Class receiverClass, String name, Definition definition) { // first try whitelist for (Class clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) { - RuntimeClass struct = definition.runtimeMap.get(clazz); + RuntimeClass struct = Definition.getRuntimeClass(clazz); if (struct != null) { MethodHandle handle = struct.getters.get(name); @@ -210,7 +210,7 @@ public final class Def { } for (final Class iface : clazz.getInterfaces()) { - struct = definition.runtimeMap.get(iface); + struct = Definition.getRuntimeClass(iface); if (struct != null) { MethodHandle handle = struct.getters.get(name); @@ -271,7 +271,7 @@ public final class Def { static MethodHandle lookupSetter(Class receiverClass, String name, Definition definition) { // first try whitelist for (Class clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) { - RuntimeClass struct = definition.runtimeMap.get(clazz); + RuntimeClass struct = Definition.getRuntimeClass(clazz); if (struct != null) { MethodHandle handle = struct.setters.get(name); @@ -281,7 +281,7 @@ public final class Def { } for (final Class iface : clazz.getInterfaces()) { - struct = definition.runtimeMap.get(iface); + struct = Definition.getRuntimeClass(iface); if (struct != null) { MethodHandle handle = struct.setters.get(name); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java index 8013361dd9b..2557d41f6ae 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java @@ -47,29 +47,29 @@ public final class Definition { public static final Definition INSTANCE = new Definition(new Definition()); /** Some native types as constants: */ - public static final Type voidType = INSTANCE.getType("void"); - public static final Type booleanType = INSTANCE.getType("boolean"); - public static final Type booleanobjType = INSTANCE.getType("Boolean"); - public static final Type byteType = INSTANCE.getType("byte"); - public static final Type byteobjType = INSTANCE.getType("Byte"); - public static final Type shortType = INSTANCE.getType("short"); - public static final Type shortobjType = INSTANCE.getType("Short"); - public static final Type intType = INSTANCE.getType("int"); - public static final Type intobjType = INSTANCE.getType("Integer"); - public static final Type longType = INSTANCE.getType("long"); - public static final Type longobjType = INSTANCE.getType("Long"); - public static final Type floatType = INSTANCE.getType("float"); - public static final Type floatobjType = INSTANCE.getType("Float"); - public static final Type doubleType = INSTANCE.getType("double"); - public static final Type doubleobjType = INSTANCE.getType("Double"); - public static final Type charType = INSTANCE.getType("char"); - public static final Type charobjType = INSTANCE.getType("Character"); - public static final Type objectType = INSTANCE.getType("Object"); - public static final Type defType = INSTANCE.getType("def"); - public static final Type defobjType = INSTANCE.getType("Def"); - public static final Type stringType = INSTANCE.getType("String"); - public static final Type exceptionType = INSTANCE.getType("Exception"); - public static final Type utilityType = INSTANCE.getType("Utility"); + public static final Type voidType = getType("void"); + public static final Type booleanType = getType("boolean"); + public static final Type booleanobjType = getType("Boolean"); + public static final Type byteType = getType("byte"); + public static final Type byteobjType = getType("Byte"); + public static final Type shortType = getType("short"); + public static final Type shortobjType = getType("Short"); + public static final Type intType = getType("int"); + public static final Type intobjType = getType("Integer"); + public static final Type longType = getType("long"); + public static final Type longobjType = getType("Long"); + public static final Type floatType = getType("float"); + public static final Type floatobjType = getType("Float"); + public static final Type doubleType = getType("double"); + public static final Type doubleobjType = getType("Double"); + public static final Type charType = getType("char"); + public static final Type charobjType = getType("Character"); + public static final Type objectType = getType("Object"); + public static final Type defType = getType("def"); + public static final Type defobjType = getType("Def"); + public static final Type stringType = getType("String"); + public static final Type exceptionType = getType("Exception"); + public static final Type utilityType = getType("Utility"); public enum Sort { VOID( void.class , 0 , true , false , false , false ), @@ -394,8 +394,29 @@ public final class Definition { } } - final Map transformsMap; - final Map, RuntimeClass> runtimeMap; + + /** Gets the type given by its name */ + public static Type getType(final String name) { + return INSTANCE.getTypeInternal(name); + } + + /** Creates an array type from the given Struct. */ + public static Type getType(final Struct struct, final int dimensions) { + return INSTANCE.getTypeInternal(struct, dimensions); + } + + public static RuntimeClass getRuntimeClass(Class clazz) { + return INSTANCE.runtimeMap.get(clazz); + } + + public static Cast getTransform(Cast cast) { + return INSTANCE.transformsMap.get(cast); + } + + // INTERNAL IMPLEMENTATION: + + private final Map transformsMap; + private final Map, RuntimeClass> runtimeMap; private final Map structsMap; private final Map simpleTypesMap; @@ -531,26 +552,26 @@ public final class Definition { } private void addTransforms() { - Type booleanType = getType("boolean"); - Type objectType = getType("Object"); - Type defType = getType("def"); - Type booleanobjType = getType("Boolean"); - Type byteType = getType("byte"); - Type shortType = getType("short"); - Type intType = getType("int"); - Type charType = getType("char"); - Type longType = getType("long"); - Type floatType = getType("float"); - Type doubleType = getType("double"); - Type numberType = getType("Number"); - Type byteobjType = getType("Byte"); - Type shortobjType = getType("Short"); - Type charobjType = getType("Character"); - Type intobjType = getType("Integer"); - Type longobjType = getType("Long"); - Type floatobjType = getType("Float"); - Type doubleobjType = getType("Double"); - Type stringType = getType("String"); + Type booleanType = getTypeInternal("boolean"); + Type objectType = getTypeInternal("Object"); + Type defType = getTypeInternal("def"); + Type booleanobjType = getTypeInternal("Boolean"); + Type byteType = getTypeInternal("byte"); + Type shortType = getTypeInternal("short"); + Type intType = getTypeInternal("int"); + Type charType = getTypeInternal("char"); + Type longType = getTypeInternal("long"); + Type floatType = getTypeInternal("float"); + Type doubleType = getTypeInternal("double"); + Type numberType = getTypeInternal("Number"); + Type byteobjType = getTypeInternal("Byte"); + Type shortobjType = getTypeInternal("Short"); + Type charobjType = getTypeInternal("Character"); + Type intobjType = getTypeInternal("Integer"); + Type longobjType = getTypeInternal("Long"); + Type floatobjType = getTypeInternal("Float"); + Type doubleobjType = getTypeInternal("Double"); + Type stringType = getTypeInternal("String"); addTransform(booleanType, objectType, "Boolean", "valueOf", true, false); addTransform(booleanType, defType, "Boolean", "valueOf", true, false); @@ -848,7 +869,7 @@ public final class Definition { final Struct struct = new Struct(name, clazz, org.objectweb.asm.Type.getType(clazz)); structsMap.put(name, struct); - simpleTypesMap.put(name, getType(name)); + simpleTypesMap.put(name, getTypeInternal(name)); } private final void addConstructorInternal(final String struct, final String name, final Type[] args) { @@ -919,7 +940,7 @@ public final class Definition { throw new IllegalArgumentException("Malformed signature: " + signature); } // method or field type (e.g. return type) - Type rtn = getType(elements[0]); + Type rtn = getTypeInternal(elements[0]); int parenIndex = elements[1].indexOf('('); if (parenIndex != -1) { // method or ctor @@ -929,7 +950,7 @@ public final class Definition { String arguments[] = elements[1].substring(parenIndex + 1, parenEnd).split(","); args = new Type[arguments.length]; for (int i = 0; i < arguments.length; i++) { - args[i] = getType(arguments[i]); + args[i] = getTypeInternal(arguments[i]); } } else { args = new Type[0]; @@ -1275,7 +1296,7 @@ public final class Definition { if (!owner.clazz.isAssignableFrom(from.clazz)) { if (from.clazz.isAssignableFrom(owner.clazz)) { - upcast = getType(owner.name); + upcast = getTypeInternal(owner.name); } else { throw new ClassCastException("Transform with owner struct [" + owner.name + "]" + " and cast type from [" + from.name + "] to cast type to [" + to.name + "] using" + @@ -1351,7 +1372,7 @@ public final class Definition { runtimeMap.put(struct.clazz, new RuntimeClass(methods, getters, setters)); } - public final Type getType(final String name) { + private Type getTypeInternal(final String name) { // simple types (e.g. 0 array dimensions) are a simple hash lookup for speed Type simple = simpleTypesMap.get(name); if (simple != null) { @@ -1365,10 +1386,10 @@ public final class Definition { throw new IllegalArgumentException("The struct with name [" + name + "] has not been defined."); } - return getType(struct, dimensions); + return getTypeInternal(struct, dimensions); } - public final Type getType(final Struct struct, final int dimensions) { + private Type getTypeInternal(final Struct struct, final int dimensions) { String name = struct.name; org.objectweb.asm.Type type = struct.type; Class clazz = struct.clazz; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Variables.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Variables.java index d0b4d706f51..417eff84249 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Variables.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Variables.java @@ -182,7 +182,7 @@ public final class Variables { final Type type; try { - type = definition.getType(typestr); + type = Definition.getType(typestr); } catch (final IllegalArgumentException exception) { throw new IllegalArgumentException("Error " + location + ": Not a type [" + typestr + "]."); } @@ -190,7 +190,7 @@ public final class Variables { boolean legal = !name.contains("<"); try { - definition.getType(name); + Definition.getType(name); legal = false; } catch (final IllegalArgumentException exception) { // Do nothing. diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java index ac0b06c0a79..0ed6fccf35f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java @@ -42,7 +42,7 @@ public final class EExplicit extends AExpression { @Override void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { try { - actual = definition.getType(this.type); + actual = Definition.getType(this.type); } catch (final IllegalArgumentException exception) { throw new IllegalArgumentException(error("Not a type [" + this.type + "].")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java index fb1b11d1d07..045c5d0e5fa 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java @@ -54,7 +54,7 @@ public final class LBrace extends ALink { index.analyze(settings, definition, variables); index = index.cast(settings, definition, variables); - after = definition.getType(before.struct, before.dimensions - 1); + after = Definition.getType(before.struct, before.dimensions - 1); return this; } else if (sort == Sort.DEF) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java index eb7fb3a6b10..6d618eb4a26 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java @@ -50,7 +50,7 @@ public final class LCast extends ALink { } try { - after = definition.getType(type); + after = Definition.getType(type); } catch (final IllegalArgumentException exception) { throw new IllegalArgumentException(error("Not a type [" + type + "].")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java index ffc90990cd6..36e4b83c117 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java @@ -55,7 +55,7 @@ public final class LNewArray extends ALink { final Type type; try { - type = definition.getType(this.type); + type = Definition.getType(this.type); } catch (final IllegalArgumentException exception) { throw new IllegalArgumentException(error("Not a type [" + this.type + "].")); } @@ -68,7 +68,7 @@ public final class LNewArray extends ALink { arguments.set(argument, expression.cast(settings, definition, variables)); } - after = definition.getType(type.struct, arguments.size()); + after = Definition.getType(type.struct, arguments.size()); return this; } @@ -87,7 +87,7 @@ public final class LNewArray extends ALink { if (arguments.size() > 1) { adapter.visitMultiANewArrayInsn(after.type.getDescriptor(), after.type.getDimensions()); } else { - adapter.newArray(definition.getType(after.struct, 0).type); + adapter.newArray(Definition.getType(after.struct, 0).type); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java index 227b63cf31f..784935e2aee 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java @@ -57,7 +57,7 @@ public final class LNewObj extends ALink { final Type type; try { - type = definition.getType(this.type); + type = Definition.getType(this.type); } catch (final IllegalArgumentException exception) { throw new IllegalArgumentException(error("Not a type [" + this.type + "].")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LVariable.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LVariable.java index 35a652f5b84..2c6ded3b4ec 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LVariable.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LVariable.java @@ -51,7 +51,7 @@ public final class LVariable extends ALink { Type type = null; try { - type = definition.getType(name); + type = Definition.getType(name); } catch (final IllegalArgumentException exception) { // Do nothing. } From 4ffa92c7c14b57cf7b9723ca1a1fddfda2f35940 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Fri, 20 May 2016 12:35:08 +0200 Subject: [PATCH 14/22] Remove the Definition instance passed around everywhere --- .../org/elasticsearch/painless/Analyzer.java | 6 +- .../painless/AnalyzerCaster.java | 27 ++- .../org/elasticsearch/painless/Compiler.java | 4 +- .../java/org/elasticsearch/painless/Def.java | 9 +- .../elasticsearch/painless/DefBootstrap.java | 6 +- .../elasticsearch/painless/Definition.java | 7 +- .../elasticsearch/painless/MethodWriter.java | 4 +- .../org/elasticsearch/painless/Variables.java | 4 +- .../org/elasticsearch/painless/Writer.java | 10 +- .../painless/node/AExpression.java | 15 +- .../elasticsearch/painless/node/ALink.java | 9 +- .../painless/node/AStatement.java | 5 +- .../elasticsearch/painless/node/EBinary.java | 168 +++++++++--------- .../elasticsearch/painless/node/EBool.java | 28 +-- .../elasticsearch/painless/node/EBoolean.java | 4 +- .../elasticsearch/painless/node/ECast.java | 7 +- .../elasticsearch/painless/node/EChain.java | 76 ++++---- .../elasticsearch/painless/node/EComp.java | 120 ++++++------- .../painless/node/EConditional.java | 24 +-- .../painless/node/EConstant.java | 4 +- .../elasticsearch/painless/node/EDecimal.java | 4 +- .../painless/node/EExplicit.java | 12 +- .../elasticsearch/painless/node/ENull.java | 4 +- .../elasticsearch/painless/node/ENumeric.java | 4 +- .../elasticsearch/painless/node/EUnary.java | 48 ++--- .../painless/node/LArrayLength.java | 8 +- .../elasticsearch/painless/node/LBrace.java | 20 +-- .../elasticsearch/painless/node/LCall.java | 16 +- .../elasticsearch/painless/node/LCast.java | 10 +- .../painless/node/LDefArray.java | 14 +- .../elasticsearch/painless/node/LDefCall.java | 14 +- .../painless/node/LDefField.java | 8 +- .../elasticsearch/painless/node/LField.java | 20 +-- .../painless/node/LListShortcut.java | 14 +- .../painless/node/LMapShortcut.java | 14 +- .../painless/node/LNewArray.java | 14 +- .../elasticsearch/painless/node/LNewObj.java | 14 +- .../painless/node/LShortcut.java | 8 +- .../elasticsearch/painless/node/LString.java | 8 +- .../painless/node/LVariable.java | 8 +- .../elasticsearch/painless/node/SBlock.java | 9 +- .../elasticsearch/painless/node/SBreak.java | 5 +- .../painless/node/SContinue.java | 5 +- .../painless/node/SDeclBlock.java | 9 +- .../painless/node/SDeclaration.java | 11 +- .../org/elasticsearch/painless/node/SDo.java | 14 +- .../painless/node/SExpression.java | 10 +- .../org/elasticsearch/painless/node/SFor.java | 26 +-- .../elasticsearch/painless/node/SIfElse.java | 18 +- .../elasticsearch/painless/node/SReturn.java | 10 +- .../elasticsearch/painless/node/SSource.java | 9 +- .../elasticsearch/painless/node/SThrow.java | 10 +- .../elasticsearch/painless/node/STrap.java | 9 +- .../org/elasticsearch/painless/node/STry.java | 13 +- .../elasticsearch/painless/node/SWhile.java | 14 +- 55 files changed, 472 insertions(+), 499 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Analyzer.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Analyzer.java index f215e39ad01..2cd62b4c3d4 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Analyzer.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Analyzer.java @@ -26,10 +26,10 @@ import org.elasticsearch.painless.node.SSource; * Runs the analysis phase of compilation using the Painless AST. */ final class Analyzer { - static Variables analyze(final CompilerSettings settings, final Definition definition, + static Variables analyze(final CompilerSettings settings, final Reserved shortcut, final SSource root) { - final Variables variables = new Variables(settings, definition, shortcut); - root.analyze(settings, definition, variables); + final Variables variables = new Variables(settings, shortcut); + root.analyze(settings, variables); return variables; } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java index bff486a60c5..2495d2edacd 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java @@ -33,8 +33,7 @@ import java.lang.reflect.InvocationTargetException; */ public final class AnalyzerCaster { - public static Cast getLegalCast(final Definition definition, - final String location, final Type actual, final Type expected, final boolean explicit) { + public static Cast getLegalCast(final String location, final Type actual, final Type expected, final boolean explicit) { final Cast cast = new Cast(actual, expected, explicit); if (actual.equals(expected)) { @@ -115,7 +114,7 @@ public final class AnalyzerCaster { } } - public static Type promoteNumeric(final Definition definition, final Type from, final boolean decimal, final boolean primitive) { + public static Type promoteNumeric(final Type from, final boolean decimal, final boolean primitive) { final Sort sort = from.sort; if (sort == Sort.DEF) { @@ -136,8 +135,7 @@ public final class AnalyzerCaster { return null; } - public static Type promoteNumeric(final Definition definition, - final Type from0, final Type from1, final boolean decimal, final boolean primitive) { + public static Type promoteNumeric(final Type from0, final Type from1, final boolean decimal, final boolean primitive) { final Sort sort0 = from0.sort; final Sort sort1 = from1.sort; @@ -171,7 +169,7 @@ public final class AnalyzerCaster { return null; } - public static Type promoteAdd(final Definition definition, final Type from0, final Type from1) { + public static Type promoteAdd(final Type from0, final Type from1) { final Sort sort0 = from0.sort; final Sort sort1 = from1.sort; @@ -179,10 +177,10 @@ public final class AnalyzerCaster { return Definition.stringType; } - return promoteNumeric(definition, from0, from1, true, true); + return promoteNumeric(from0, from1, true, true); } - public static Type promoteXor(final Definition definition, final Type from0, final Type from1) { + public static Type promoteXor(final Type from0, final Type from1) { final Sort sort0 = from0.sort; final Sort sort1 = from1.sort; @@ -190,10 +188,10 @@ public final class AnalyzerCaster { return Definition.booleanType; } - return promoteNumeric(definition, from0, from1, false, true); + return promoteNumeric(from0, from1, false, true); } - public static Type promoteEquality(final Definition definition, final Type from0, final Type from1) { + public static Type promoteEquality(final Type from0, final Type from1) { final Sort sort0 = from0.sort; final Sort sort1 = from1.sort; @@ -208,13 +206,13 @@ public final class AnalyzerCaster { } if (sort0.numeric && sort1.numeric) { - return promoteNumeric(definition, from0, from1, true, primitive); + return promoteNumeric(from0, from1, true, primitive); } return Definition.objectType; } - public static Type promoteReference(final Definition definition, final Type from0, final Type from1) { + public static Type promoteReference(final Type from0, final Type from1) { final Sort sort0 = from0.sort; final Sort sort1 = from1.sort; @@ -228,15 +226,14 @@ public final class AnalyzerCaster { } if (sort0.numeric && sort1.numeric) { - return promoteNumeric(definition, from0, from1, true, true); + return promoteNumeric(from0, from1, true, true); } } return Definition.objectType; } - public static Type promoteConditional(final Definition definition, - final Type from0, final Type from1, final Object const0, final Object const1) { + public static Type promoteConditional(final Type from0, final Type from1, final Object const0, final Object const1) { if (from0.equals(from1)) { return from0; } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Compiler.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Compiler.java index c487dddba71..65d7c78555c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Compiler.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Compiler.java @@ -113,9 +113,9 @@ final class Compiler { final Reserved reserved = new Reserved(); final SSource root = Walker.buildPainlessTree(source, reserved); - final Variables variables = Analyzer.analyze(settings, Definition.INSTANCE, reserved, root); + final Variables variables = Analyzer.analyze(settings, reserved, root); - return Writer.write(settings, Definition.INSTANCE, name, source, variables, root); + return Writer.write(settings, name, source, variables, root); } /** diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java index de9e1c43bea..c4bebee7443 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Def.java @@ -135,11 +135,10 @@ public final class Def { * @param receiverClass Class of the object to invoke the method on. * @param name Name of the method. * @param type Callsite signature. Need not match exactly, except the number of parameters. - * @param definition Whitelist to check. * @return pointer to matching method to invoke. never returns null. * @throws IllegalArgumentException if no matching whitelisted method was found. */ - static MethodHandle lookupMethod(Class receiverClass, String name, MethodType type, Definition definition) { + static MethodHandle lookupMethod(Class receiverClass, String name, MethodType type) { // we don't consider receiver an argument/counting towards arity type = type.dropParameterTypes(0, 1); Definition.MethodKey key = new Definition.MethodKey(name, type.parameterCount()); @@ -193,11 +192,10 @@ public final class Def { *

* @param receiverClass Class of the object to retrieve the field from. * @param name Name of the field. - * @param definition Whitelist to check. * @return pointer to matching field. never returns null. * @throws IllegalArgumentException if no matching whitelisted field was found. */ - static MethodHandle lookupGetter(Class receiverClass, String name, Definition definition) { + static MethodHandle lookupGetter(Class receiverClass, String name) { // first try whitelist for (Class clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) { RuntimeClass struct = Definition.getRuntimeClass(clazz); @@ -264,11 +262,10 @@ public final class Def { *

* @param receiverClass Class of the object to retrieve the field from. * @param name Name of the field. - * @param definition Whitelist to check. * @return pointer to matching field. never returns null. * @throws IllegalArgumentException if no matching whitelisted field was found. */ - static MethodHandle lookupSetter(Class receiverClass, String name, Definition definition) { + static MethodHandle lookupSetter(Class receiverClass, String name) { // first try whitelist for (Class clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) { RuntimeClass struct = Definition.getRuntimeClass(clazz); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefBootstrap.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefBootstrap.java index 380f5455ab3..40b9cc6cbe8 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefBootstrap.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefBootstrap.java @@ -94,11 +94,11 @@ public final class DefBootstrap { private static MethodHandle lookup(int flavor, Class clazz, String name, MethodType type) { switch(flavor) { case METHOD_CALL: - return Def.lookupMethod(clazz, name, type, Definition.INSTANCE); + return Def.lookupMethod(clazz, name, type); case LOAD: - return Def.lookupGetter(clazz, name, Definition.INSTANCE); + return Def.lookupGetter(clazz, name); case STORE: - return Def.lookupSetter(clazz, name, Definition.INSTANCE); + return Def.lookupSetter(clazz, name); case ARRAY_LOAD: return Def.lookupArrayLoad(clazz); case ARRAY_STORE: diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java index 2557d41f6ae..0a81188e776 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java @@ -40,11 +40,8 @@ public final class Definition { private static final String DEFINITION_FILE = "definition.txt"; - /** - * The default language API to be used with Painless. The second construction is used - * to finalize all the variables, so there is no mistake of modification afterwards. - */ - public static final Definition INSTANCE = new Definition(new Definition()); + // The second construction is used to finalize all the variables, so there is no mistake of modification afterwards. + private static final Definition INSTANCE = new Definition(new Definition()); /** Some native types as constants: */ public static final Type voidType = getType("void"); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java index ce1bb531655..cddd1326c74 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java @@ -200,9 +200,7 @@ public final class MethodWriter extends GeneratorAdapter { } } - public void writeBinaryInstruction(final Definition definition, - final String location, - final Type type, final Operation operation) { + public void writeBinaryInstruction(final String location, final Type type, final Operation operation) { final Sort sort = type.sort; if ((sort == Sort.FLOAT || sort == Sort.DOUBLE) && diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Variables.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Variables.java index 417eff84249..28a7416d800 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Variables.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Variables.java @@ -86,14 +86,12 @@ public final class Variables { } } - private final Definition definition; final Reserved reserved; private final Deque scopes = new ArrayDeque<>(); private final Deque variables = new ArrayDeque<>(); - public Variables(final CompilerSettings settings, final Definition definition, final Reserved reserved) { - this.definition = definition; + public Variables(final CompilerSettings settings, final Reserved reserved) { this.reserved = reserved; incrementScope(); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Writer.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Writer.java index 449361867b9..977a591b7af 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Writer.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Writer.java @@ -38,15 +38,14 @@ import static org.elasticsearch.painless.WriterConstants.MAP_TYPE; */ final class Writer { - static byte[] write(final CompilerSettings settings, final Definition definition, + static byte[] write(final CompilerSettings settings, String name, final String source, final Variables variables, final SSource root) { - final Writer writer = new Writer(settings, definition, name, source, variables, root); + final Writer writer = new Writer(settings, name, source, variables, root); return writer.getBytes(); } private final CompilerSettings settings; - private final Definition definition; private final String scriptName; private final String source; private final Variables variables; @@ -55,10 +54,9 @@ final class Writer { private final ClassWriter writer; private final MethodWriter adapter; - private Writer(final CompilerSettings settings, final Definition definition, + private Writer(final CompilerSettings settings, String name, final String source, final Variables variables, final SSource root) { this.settings = settings; - this.definition = definition; this.scriptName = name; this.source = source; this.variables = variables; @@ -177,7 +175,7 @@ final class Writer { adapter.visitVarInsn(Opcodes.ISTORE, loop.slot); } - root.write(settings, definition, adapter); + root.write(settings, adapter); adapter.endMethod(); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java index 528da4384c8..f741d62921f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java @@ -20,7 +20,6 @@ package org.elasticsearch.painless.node; import org.elasticsearch.painless.CompilerSettings; -import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Cast; import org.elasticsearch.painless.Definition.Type; import org.elasticsearch.painless.AnalyzerCaster; @@ -101,27 +100,27 @@ public abstract class AExpression extends ANode { /** * Checks for errors and collects data for the writing phase. */ - abstract void analyze(final CompilerSettings settings, final Definition definition, final Variables variables); + abstract void analyze(final CompilerSettings settings, final Variables variables); /** * Writes ASM based on the data collected during the analysis phase. */ - abstract void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter); + abstract void write(final CompilerSettings settings, final MethodWriter adapter); /** * Inserts {@link ECast} nodes into the tree for implicit casts. Also replaces * nodes with the constant variable set to a non-null value with {@link EConstant}. * @return The new child node for the parent node calling this method. */ - AExpression cast(final CompilerSettings settings, final Definition definition, final Variables variables) { - final Cast cast = AnalyzerCaster.getLegalCast(definition, location, actual, expected, explicit); + AExpression cast(final CompilerSettings settings, final Variables variables) { + final Cast cast = AnalyzerCaster.getLegalCast(location, actual, expected, explicit); if (cast == null) { if (constant == null || this instanceof EConstant) { return this; } else { final EConstant econstant = new EConstant(line, location, constant); - econstant.analyze(settings, definition, variables); + econstant.analyze(settings, variables); if (!expected.equals(econstant.actual)) { throw new IllegalStateException(error("Illegal tree structure.")); @@ -142,7 +141,7 @@ public abstract class AExpression extends ANode { constant = AnalyzerCaster.constCast(location, constant, cast); final EConstant econstant = new EConstant(line, location, constant); - econstant.analyze(settings, definition, variables); + econstant.analyze(settings, variables); if (!expected.equals(econstant.actual)) { throw new IllegalStateException(error("Illegal tree structure.")); @@ -156,7 +155,7 @@ public abstract class AExpression extends ANode { return ecast; } else { final EConstant econstant = new EConstant(line, location, constant); - econstant.analyze(settings, definition, variables); + econstant.analyze(settings, variables); if (!actual.equals(econstant.actual)) { throw new IllegalStateException(error("Illegal tree structure.")); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ALink.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ALink.java index ffbfff112b3..8f8e226006e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ALink.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ALink.java @@ -20,7 +20,6 @@ package org.elasticsearch.painless.node; import org.elasticsearch.painless.CompilerSettings; -import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Type; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -87,22 +86,22 @@ public abstract class ALink extends ANode { * def or a shortcut is used. Otherwise, returns itself. This will be * updated into the {@link EChain} node's list of links. */ - abstract ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables); + abstract ALink analyze(final CompilerSettings settings, final Variables variables); /** * Write values before a load/store occurs such as an array index. */ - abstract void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter); + abstract void write(final CompilerSettings settings, final MethodWriter adapter); /** * Write a load for the specific link type. */ - abstract void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter); + abstract void load(final CompilerSettings settings, final MethodWriter adapter); /** * Write a store for the specific link type. */ - abstract void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter); + abstract void store(final CompilerSettings settings, final MethodWriter adapter); /** * Used to copy link data from one to another during analysis in the case of replacement. diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AStatement.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AStatement.java index 569e8cfb03b..f80d5e7b4fd 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AStatement.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AStatement.java @@ -20,7 +20,6 @@ package org.elasticsearch.painless.node; import org.elasticsearch.painless.CompilerSettings; -import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.objectweb.asm.Label; import org.elasticsearch.painless.MethodWriter; @@ -116,10 +115,10 @@ public abstract class AStatement extends ANode { /** * Checks for errors and collects data for the writing phase. */ - abstract void analyze(final CompilerSettings settings, final Definition definition, final Variables variables); + abstract void analyze(final CompilerSettings settings, final Variables variables); /** * Writes ASM based on the data collected during the analysis phase. */ - abstract void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter); + abstract void write(final CompilerSettings settings, final MethodWriter adapter); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java index 92ccf60a200..38871d007f4 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java @@ -48,39 +48,39 @@ public final class EBinary extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { if (operation == Operation.MUL) { - analyzeMul(settings, definition, variables); + analyzeMul(settings, variables); } else if (operation == Operation.DIV) { - analyzeDiv(settings, definition, variables); + analyzeDiv(settings, variables); } else if (operation == Operation.REM) { - analyzeRem(settings, definition, variables); + analyzeRem(settings, variables); } else if (operation == Operation.ADD) { - analyzeAdd(settings, definition, variables); + analyzeAdd(settings, variables); } else if (operation == Operation.SUB) { - analyzeSub(settings, definition, variables); + analyzeSub(settings, variables); } else if (operation == Operation.LSH) { - analyzeLSH(settings, definition, variables); + analyzeLSH(settings, variables); } else if (operation == Operation.RSH) { - analyzeRSH(settings, definition, variables); + analyzeRSH(settings, variables); } else if (operation == Operation.USH) { - analyzeUSH(settings, definition, variables); + analyzeUSH(settings, variables); } else if (operation == Operation.BWAND) { - analyzeBWAnd(settings, definition, variables); + analyzeBWAnd(settings, variables); } else if (operation == Operation.XOR) { - analyzeXor(settings, definition, variables); + analyzeXor(settings, variables); } else if (operation == Operation.BWOR) { - analyzeBWOr(settings, definition, variables); + analyzeBWOr(settings, variables); } else { throw new IllegalStateException(error("Illegal tree structure.")); } } - private void analyzeMul(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeMul(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); if (promote == null) { throw new ClassCastException(error("Cannot apply multiply [*] to types " + @@ -90,8 +90,8 @@ public final class EBinary extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -112,11 +112,11 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeDiv(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeDiv(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); if (promote == null) { throw new ClassCastException(error("Cannot apply divide [/] to types " + @@ -126,8 +126,8 @@ public final class EBinary extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -148,11 +148,11 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeRem(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeRem(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); if (promote == null) { throw new ClassCastException(error("Cannot apply remainder [%] to types " + @@ -162,8 +162,8 @@ public final class EBinary extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -184,11 +184,11 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeAdd(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeAdd(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteAdd(definition, left.actual, right.actual); + final Type promote = AnalyzerCaster.promoteAdd(left.actual, right.actual); if (promote == null) { throw new ClassCastException(error("Cannot apply add [+] to types " + @@ -214,8 +214,8 @@ public final class EBinary extends AExpression { right.expected = promote; } - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { if (sort == Sort.INT) { @@ -236,11 +236,11 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeSub(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeSub(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); if (promote == null) { throw new ClassCastException(error("Cannot apply subtract [-] to types " + @@ -250,8 +250,8 @@ public final class EBinary extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -272,11 +272,11 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeLSH(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeLSH(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, false, true); + final Type promote = AnalyzerCaster.promoteNumeric(left.actual, false, true); if (promote == null) { throw new ClassCastException(error("Cannot apply left shift [<<] to types " + @@ -287,8 +287,8 @@ public final class EBinary extends AExpression { right.expected = Definition.intType; right.explicit = true; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -305,11 +305,11 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeRSH(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeRSH(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, false, true); + final Type promote = AnalyzerCaster.promoteNumeric(left.actual, false, true); if (promote == null) { throw new ClassCastException(error("Cannot apply right shift [>>] to types " + @@ -320,8 +320,8 @@ public final class EBinary extends AExpression { right.expected = Definition.intType; right.explicit = true; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -338,11 +338,11 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeUSH(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeUSH(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, false, true); + final Type promote = AnalyzerCaster.promoteNumeric(left.actual, false, true); if (promote == null) { throw new ClassCastException(error("Cannot apply unsigned shift [>>>] to types " + @@ -353,8 +353,8 @@ public final class EBinary extends AExpression { right.expected = Definition.intType; right.explicit = true; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -371,11 +371,11 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeBWAnd(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeBWAnd(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, false, true); + final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, false, true); if (promote == null) { throw new ClassCastException(error("Cannot apply and [&] to types " + @@ -385,8 +385,8 @@ public final class EBinary extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -403,11 +403,11 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeXor(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeXor(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteXor(definition, left.actual, right.actual); + final Type promote = AnalyzerCaster.promoteXor(left.actual, right.actual); if (promote == null) { throw new ClassCastException(error("Cannot apply xor [^] to types " + @@ -417,8 +417,8 @@ public final class EBinary extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -437,11 +437,11 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeBWOr(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeBWOr(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, false, true); + final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, false, true); if (promote == null) { throw new ClassCastException(error("Cannot apply or [|] to types " + @@ -451,8 +451,8 @@ public final class EBinary extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -470,19 +470,19 @@ public final class EBinary extends AExpression { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { if (actual.sort == Sort.STRING && operation == Operation.ADD) { if (!cat) { adapter.writeNewStrings(); } - left.write(settings, definition, adapter); + left.write(settings, adapter); if (!(left instanceof EBinary) || ((EBinary)left).operation != Operation.ADD || left.actual.sort != Sort.STRING) { adapter.writeAppendStrings(left.actual); } - right.write(settings, definition, adapter); + right.write(settings, adapter); if (!(right instanceof EBinary) || ((EBinary)right).operation != Operation.ADD || right.actual.sort != Sort.STRING) { adapter.writeAppendStrings(right.actual); @@ -492,10 +492,10 @@ public final class EBinary extends AExpression { adapter.writeToStrings(); } } else { - left.write(settings, definition, adapter); - right.write(settings, definition, adapter); + left.write(settings, adapter); + right.write(settings, adapter); - adapter.writeBinaryInstruction(definition, location, actual, operation); + adapter.writeBinaryInstruction(location, actual, operation); } adapter.writeBranch(tru, fals); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java index 1cd2564b0e1..28072b9d9bd 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java @@ -44,14 +44,14 @@ public final class EBool extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { left.expected = Definition.booleanType; - left.analyze(settings, definition, variables); - left = left.cast(settings, definition, variables); + left.analyze(settings, variables); + left = left.cast(settings, variables); right.expected = Definition.booleanType; - right.analyze(settings, definition, variables); - right = right.cast(settings, definition, variables); + right.analyze(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { if (operation == Operation.AND) { @@ -67,7 +67,7 @@ public final class EBool extends AExpression { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { if (tru != null || fals != null) { if (operation == Operation.AND) { final Label localfals = fals == null ? new Label() : fals; @@ -76,8 +76,8 @@ public final class EBool extends AExpression { right.tru = tru; right.fals = fals; - left.write(settings, definition, adapter); - right.write(settings, definition, adapter); + left.write(settings, adapter); + right.write(settings, adapter); if (fals == null) { adapter.mark(localfals); @@ -89,8 +89,8 @@ public final class EBool extends AExpression { right.tru = tru; right.fals = fals; - left.write(settings, definition, adapter); - right.write(settings, definition, adapter); + left.write(settings, adapter); + right.write(settings, adapter); if (tru == null) { adapter.mark(localtru); @@ -106,8 +106,8 @@ public final class EBool extends AExpression { left.fals = localfals; right.fals = localfals; - left.write(settings, definition, adapter); - right.write(settings, definition, adapter); + left.write(settings, adapter); + right.write(settings, adapter); adapter.push(true); adapter.goTo(end); @@ -122,8 +122,8 @@ public final class EBool extends AExpression { left.tru = localtru; right.fals = localfals; - left.write(settings, definition, adapter); - right.write(settings, definition, adapter); + left.write(settings, adapter); + right.write(settings, adapter); adapter.mark(localtru); adapter.push(true); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java index 24f1ac899e8..979fbed03e3 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java @@ -36,12 +36,12 @@ public final class EBoolean extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { actual = Definition.booleanType; } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { throw new IllegalArgumentException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECast.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECast.java index d68c95c910a..c46957f78d9 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECast.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECast.java @@ -20,7 +20,6 @@ package org.elasticsearch.painless.node; import org.elasticsearch.painless.CompilerSettings; -import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Cast; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -46,13 +45,13 @@ final class ECast extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { throw new IllegalStateException(error("Illegal tree structure.")); } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { - child.write(settings, definition, adapter); + void write(final CompilerSettings settings, final MethodWriter adapter) { + child.write(settings, adapter); adapter.writeCast(cast); adapter.writeBranch(tru, fals); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java index a3c0c656fda..d992edd8505 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java @@ -59,20 +59,20 @@ public final class EChain extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - analyzeLinks(settings, definition, variables); + void analyze(final CompilerSettings settings, final Variables variables) { + analyzeLinks(settings, variables); analyzeIncrDecr(); if (operation != null) { - analyzeCompound(settings, definition, variables); + analyzeCompound(settings, variables); } else if (expression != null) { - analyzeWrite(settings, definition, variables); + analyzeWrite(settings, variables); } else { analyzeRead(); } } - private void analyzeLinks(final CompilerSettings settings, final Definition definition, final Variables variables) { + private void analyzeLinks(final CompilerSettings settings, final Variables variables) { ALink previous = null; int index = 0; @@ -92,7 +92,7 @@ public final class EChain extends AExpression { current.store = expression != null || pre || post; } - final ALink analyzed = current.analyze(settings, definition, variables); + final ALink analyzed = current.analyze(settings, variables); if (analyzed == null) { links.remove(index); @@ -153,33 +153,33 @@ public final class EChain extends AExpression { } } - private void analyzeCompound(final CompilerSettings settings, final Definition definition, final Variables variables) { + private void analyzeCompound(final CompilerSettings settings, final Variables variables) { final ALink last = links.get(links.size() - 1); - expression.analyze(settings, definition, variables); + expression.analyze(settings, variables); if (operation == Operation.MUL) { - promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true, true); + promote = AnalyzerCaster.promoteNumeric(last.after, expression.actual, true, true); } else if (operation == Operation.DIV) { - promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true, true); + promote = AnalyzerCaster.promoteNumeric(last.after, expression.actual, true, true); } else if (operation == Operation.REM) { - promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true, true); + promote = AnalyzerCaster.promoteNumeric(last.after, expression.actual, true, true); } else if (operation == Operation.ADD) { - promote = AnalyzerCaster.promoteAdd(definition, last.after, expression.actual); + promote = AnalyzerCaster.promoteAdd(last.after, expression.actual); } else if (operation == Operation.SUB) { - promote = AnalyzerCaster.promoteNumeric(definition, last.after, expression.actual, true, true); + promote = AnalyzerCaster.promoteNumeric(last.after, expression.actual, true, true); } else if (operation == Operation.LSH) { - promote = AnalyzerCaster.promoteNumeric(definition, last.after, false, true); + promote = AnalyzerCaster.promoteNumeric(last.after, false, true); } else if (operation == Operation.RSH) { - promote = AnalyzerCaster.promoteNumeric(definition, last.after, false, true); + promote = AnalyzerCaster.promoteNumeric(last.after, false, true); } else if (operation == Operation.USH) { - promote = AnalyzerCaster.promoteNumeric(definition, last.after, false, true); + promote = AnalyzerCaster.promoteNumeric(last.after, false, true); } else if (operation == Operation.BWAND) { - promote = AnalyzerCaster.promoteXor(definition, last.after, expression.actual); + promote = AnalyzerCaster.promoteXor(last.after, expression.actual); } else if (operation == Operation.XOR) { - promote = AnalyzerCaster.promoteXor(definition, last.after, expression.actual); + promote = AnalyzerCaster.promoteXor(last.after, expression.actual); } else if (operation == Operation.BWOR) { - promote = AnalyzerCaster.promoteXor(definition, last.after, expression.actual); + promote = AnalyzerCaster.promoteXor(last.after, expression.actual); } else { throw new IllegalStateException(error("Illegal tree structure.")); } @@ -205,30 +205,30 @@ public final class EChain extends AExpression { expression.expected = promote; } - expression = expression.cast(settings, definition, variables); + expression = expression.cast(settings, variables); - there = AnalyzerCaster.getLegalCast(definition, location, last.after, promote, false); - back = AnalyzerCaster.getLegalCast(definition, location, promote, last.after, true); + there = AnalyzerCaster.getLegalCast(location, last.after, promote, false); + back = AnalyzerCaster.getLegalCast(location, promote, last.after, true); this.statement = true; this.actual = read ? last.after : Definition.voidType; } - private void analyzeWrite(final CompilerSettings settings, final Definition definition, final Variables variables) { + private void analyzeWrite(final CompilerSettings settings, final Variables variables) { final ALink last = links.get(links.size() - 1); // If the store node is a DEF node, we remove the cast to DEF from the expression // and promote the real type to it: if (last instanceof IDefLink) { - expression.analyze(settings, definition, variables); + expression.analyze(settings, variables); last.after = expression.expected = expression.actual; } else { // otherwise we adapt the type of the expression to the store type expression.expected = last.after; - expression.analyze(settings, definition, variables); + expression.analyze(settings, variables); } - expression = expression.cast(settings, definition, variables); + expression = expression.cast(settings, variables); this.statement = true; this.actual = read ? last.after : Definition.voidType; @@ -248,7 +248,7 @@ public final class EChain extends AExpression { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings,final MethodWriter adapter) { if (cat) { adapter.writeNewStrings(); } @@ -256,15 +256,15 @@ public final class EChain extends AExpression { final ALink last = links.get(links.size() - 1); for (final ALink link : links) { - link.write(settings, definition, adapter); + link.write(settings, adapter); if (link == last && link.store) { if (cat) { adapter.writeDup(link.size, 1); - link.load(settings, definition, adapter); + link.load(settings, adapter); adapter.writeAppendStrings(link.after); - expression.write(settings, definition, adapter); + expression.write(settings, adapter); if (!(expression instanceof EBinary) || ((EBinary)expression).operation != Operation.ADD || expression.actual.sort != Sort.STRING) { @@ -278,18 +278,18 @@ public final class EChain extends AExpression { adapter.writeDup(link.after.sort.size, link.size); } - link.store(settings, definition, adapter); + link.store(settings, adapter); } else if (operation != null) { adapter.writeDup(link.size, 0); - link.load(settings, definition, adapter); + link.load(settings, adapter); if (link.load && post) { adapter.writeDup(link.after.sort.size, link.size); } adapter.writeCast(there); - expression.write(settings, definition, adapter); - adapter.writeBinaryInstruction(definition, location, promote, operation); + expression.write(settings, adapter); + adapter.writeBinaryInstruction(location, promote, operation); adapter.writeCast(back); @@ -297,18 +297,18 @@ public final class EChain extends AExpression { adapter.writeDup(link.after.sort.size, link.size); } - link.store(settings, definition, adapter); + link.store(settings, adapter); } else { - expression.write(settings, definition, adapter); + expression.write(settings, adapter); if (link.load) { adapter.writeDup(link.after.sort.size, link.size); } - link.store(settings, definition, adapter); + link.store(settings, adapter); } } else { - link.load(settings, definition, adapter); + link.load(settings, adapter); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java index 82033124e1c..68c45f4870e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java @@ -54,33 +54,33 @@ public final class EComp extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { if (operation == Operation.EQ) { - analyzeEq(settings, definition, variables); + analyzeEq(settings, variables); } else if (operation == Operation.EQR) { - analyzeEqR(settings, definition, variables); + analyzeEqR(settings, variables); } else if (operation == Operation.NE) { - analyzeNE(settings, definition, variables); + analyzeNE(settings, variables); } else if (operation == Operation.NER) { - analyzeNER(settings, definition, variables); + analyzeNER(settings, variables); } else if (operation == Operation.GTE) { - analyzeGTE(settings, definition, variables); + analyzeGTE(settings, variables); } else if (operation == Operation.GT) { - analyzeGT(settings, definition, variables); + analyzeGT(settings, variables); } else if (operation == Operation.LTE) { - analyzeLTE(settings, definition, variables); + analyzeLTE(settings, variables); } else if (operation == Operation.LT) { - analyzeLT(settings, definition, variables); + analyzeLT(settings, variables); } else { throw new IllegalStateException(error("Illegal tree structure.")); } } - private void analyzeEq(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeEq(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteEquality(definition, left.actual, right.actual); + final Type promote = AnalyzerCaster.promoteEquality(left.actual, right.actual); if (promote == null) { throw new ClassCastException(error("Cannot apply equals [==] to types " + @@ -90,8 +90,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.isNull && right.isNull) { throw new IllegalArgumentException(error("Extraneous comparison of null constants.")); @@ -122,11 +122,11 @@ public final class EComp extends AExpression { actual = Definition.booleanType; } - private void analyzeEqR(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeEqR(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteReference(definition, left.actual, right.actual); + final Type promote = AnalyzerCaster.promoteReference(left.actual, right.actual); if (promote == null) { throw new ClassCastException(error("Cannot apply reference equals [===] to types " + @@ -136,8 +136,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.isNull && right.isNull) { throw new IllegalArgumentException(error("Extraneous comparison of null constants.")); @@ -164,11 +164,11 @@ public final class EComp extends AExpression { actual = Definition.booleanType; } - private void analyzeNE(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeNE(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteEquality(definition, left.actual, right.actual); + final Type promote = AnalyzerCaster.promoteEquality(left.actual, right.actual); if (promote == null) { throw new ClassCastException(error("Cannot apply not equals [!=] to types " + @@ -178,8 +178,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.isNull && right.isNull) { throw new IllegalArgumentException(error("Extraneous comparison of null constants.")); @@ -210,11 +210,11 @@ public final class EComp extends AExpression { actual = Definition.booleanType; } - private void analyzeNER(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeNER(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteReference(definition, left.actual, right.actual); + final Type promote = AnalyzerCaster.promoteReference(left.actual, right.actual); if (promote == null) { throw new ClassCastException(error("Cannot apply reference not equals [!==] to types " + @@ -224,8 +224,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.isNull && right.isNull) { throw new IllegalArgumentException(error("Extraneous comparison of null constants.")); @@ -252,11 +252,11 @@ public final class EComp extends AExpression { actual = Definition.booleanType; } - private void analyzeGTE(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeGTE(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); if (promote == null) { throw new ClassCastException(error("Cannot apply greater than or equals [>=] to types " + @@ -266,8 +266,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -288,11 +288,11 @@ public final class EComp extends AExpression { actual = Definition.booleanType; } - private void analyzeGT(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeGT(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); if (promote == null) { throw new ClassCastException(error("Cannot apply greater than [>] to types " + @@ -302,8 +302,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -324,11 +324,11 @@ public final class EComp extends AExpression { actual = Definition.booleanType; } - private void analyzeLTE(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeLTE(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); if (promote == null) { throw new ClassCastException(error("Cannot apply less than or equals [<=] to types " + @@ -338,8 +338,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -360,11 +360,11 @@ public final class EComp extends AExpression { actual = Definition.booleanType; } - private void analyzeLT(final CompilerSettings settings, final Definition definition, final Variables variables) { - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + private void analyzeLT(final CompilerSettings settings, final Variables variables) { + left.analyze(settings, variables); + right.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, left.actual, right.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); if (promote == null) { throw new ClassCastException(error("Cannot apply less than [>=] to types " + @@ -374,8 +374,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -397,15 +397,15 @@ public final class EComp extends AExpression { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { final boolean branch = tru != null || fals != null; final org.objectweb.asm.Type rtype = right.actual.type; final Sort rsort = right.actual.sort; - left.write(settings, definition, adapter); + left.write(settings, adapter); if (!right.isNull) { - right.write(settings, definition, adapter); + right.write(settings, adapter); } final Label jump = tru != null ? tru : fals != null ? fals : new Label(); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java index c1b37dfeee0..e084974fb33 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java @@ -46,10 +46,10 @@ public final class EConditional extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { condition.expected = Definition.booleanType; - condition.analyze(settings, definition, variables); - condition = condition.cast(settings, definition, variables); + condition.analyze(settings, variables); + condition = condition.cast(settings, variables); if (condition.constant != null) { throw new IllegalArgumentException(error("Extraneous conditional statement.")); @@ -61,23 +61,23 @@ public final class EConditional extends AExpression { right.explicit = explicit; actual = expected; - left.analyze(settings, definition, variables); - right.analyze(settings, definition, variables); + left.analyze(settings, variables); + right.analyze(settings, variables); if (expected == null) { - final Type promote = AnalyzerCaster.promoteConditional(definition, left.actual, right.actual, left.constant, right.constant); + final Type promote = AnalyzerCaster.promoteConditional(left.actual, right.actual, left.constant, right.constant); left.expected = promote; right.expected = promote; actual = promote; } - left = left.cast(settings, definition, variables); - right = right.cast(settings, definition, variables); + left = left.cast(settings, variables); + right = right.cast(settings, variables); } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { final Label localfals = new Label(); final Label end = new Label(); @@ -85,11 +85,11 @@ public final class EConditional extends AExpression { left.tru = right.tru = tru; left.fals = right.fals = fals; - condition.write(settings, definition, adapter); - left.write(settings, definition, adapter); + condition.write(settings, adapter); + left.write(settings, adapter); adapter.goTo(end); adapter.mark(localfals); - right.write(settings, definition, adapter); + right.write(settings, adapter); adapter.mark(end); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java index cbf547a0417..e590ee41852 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java @@ -38,7 +38,7 @@ final class EConstant extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { if (constant instanceof String) { actual = Definition.stringType; } else if (constant instanceof Double) { @@ -63,7 +63,7 @@ final class EConstant extends AExpression { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { final Sort sort = actual.sort; switch (sort) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java index 820c3b3926e..3f1d3a3fc26 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java @@ -38,7 +38,7 @@ public final class EDecimal extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { if (value.endsWith("f") || value.endsWith("F")) { try { constant = Float.parseFloat(value.substring(0, value.length() - 1)); @@ -57,7 +57,7 @@ public final class EDecimal extends AExpression { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { throw new IllegalArgumentException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java index 0ed6fccf35f..e0afd8f822a 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java @@ -40,7 +40,7 @@ public final class EExplicit extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { try { actual = Definition.getType(this.type); } catch (final IllegalArgumentException exception) { @@ -49,19 +49,19 @@ public final class EExplicit extends AExpression { child.expected = actual; child.explicit = true; - child.analyze(settings, definition, variables); - child = child.cast(settings, definition, variables); + child.analyze(settings, variables); + child = child.cast(settings, variables); } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { throw new IllegalArgumentException(error("Illegal tree structure.")); } - AExpression cast(final CompilerSettings settings, final Definition definition, final Variables variables) { + AExpression cast(final CompilerSettings settings, final Variables variables) { child.expected = expected; child.explicit = explicit; - return child.cast(settings, definition, variables); + return child.cast(settings, variables); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java index 3e003fefe5c..3fcabccff17 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java @@ -35,7 +35,7 @@ public final class ENull extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { isNull = true; if (expected != null) { @@ -50,7 +50,7 @@ public final class ENull extends AExpression { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { adapter.visitInsn(Opcodes.ACONST_NULL); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java index e8cf202d91d..e68de5b4128 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java @@ -41,7 +41,7 @@ public final class ENumeric extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { if (value.endsWith("d") || value.endsWith("D")) { if (radix != 10) { throw new IllegalStateException(error("Invalid tree structure.")); @@ -96,7 +96,7 @@ public final class ENumeric extends AExpression { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { throw new IllegalArgumentException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java index 627eb85e968..8ab97dcbde6 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java @@ -48,24 +48,24 @@ public final class EUnary extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { if (operation == Operation.NOT) { - analyzeNot(settings, definition, variables); + analyzeNot(settings, variables); } else if (operation == Operation.BWNOT) { - analyzeBWNot(settings, definition, variables); + analyzeBWNot(settings, variables); } else if (operation == Operation.ADD) { - analyzerAdd(settings, definition, variables); + analyzerAdd(settings, variables); } else if (operation == Operation.SUB) { - analyzerSub(settings, definition, variables); + analyzerSub(settings, variables); } else { throw new IllegalStateException(error("Illegal tree structure.")); } } - void analyzeNot(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyzeNot(final CompilerSettings settings, final Variables variables) { child.expected = Definition.booleanType; - child.analyze(settings, definition, variables); - child = child.cast(settings, definition, variables); + child.analyze(settings, variables); + child = child.cast(settings, variables); if (child.constant != null) { constant = !(boolean)child.constant; @@ -74,17 +74,17 @@ public final class EUnary extends AExpression { actual = Definition.booleanType; } - void analyzeBWNot(final CompilerSettings settings, final Definition definition, final Variables variables) { - child.analyze(settings, definition, variables); + void analyzeBWNot(final CompilerSettings settings, final Variables variables) { + child.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, child.actual, false, true); + final Type promote = AnalyzerCaster.promoteNumeric(child.actual, false, true); if (promote == null) { throw new ClassCastException(error("Cannot apply not [~] to type [" + child.actual.name + "].")); } child.expected = promote; - child = child.cast(settings, definition, variables); + child = child.cast(settings, variables); if (child.constant != null) { final Sort sort = promote.sort; @@ -101,17 +101,17 @@ public final class EUnary extends AExpression { actual = promote; } - void analyzerAdd(final CompilerSettings settings, final Definition definition, final Variables variables) { - child.analyze(settings, definition, variables); + void analyzerAdd(final CompilerSettings settings, final Variables variables) { + child.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, child.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(child.actual, true, true); if (promote == null) { throw new ClassCastException(error("Cannot apply positive [+] to type [" + child.actual.name + "].")); } child.expected = promote; - child = child.cast(settings, definition, variables); + child = child.cast(settings, variables); if (child.constant != null) { final Sort sort = promote.sort; @@ -132,17 +132,17 @@ public final class EUnary extends AExpression { actual = promote; } - void analyzerSub(final CompilerSettings settings, final Definition definition, final Variables variables) { - child.analyze(settings, definition, variables); + void analyzerSub(final CompilerSettings settings, final Variables variables) { + child.analyze(settings, variables); - final Type promote = AnalyzerCaster.promoteNumeric(definition, child.actual, true, true); + final Type promote = AnalyzerCaster.promoteNumeric(child.actual, true, true); if (promote == null) { throw new ClassCastException(error("Cannot apply negative [-] to type [" + child.actual.name + "].")); } child.expected = promote; - child = child.cast(settings, definition, variables); + child = child.cast(settings, variables); if (child.constant != null) { final Sort sort = promote.sort; @@ -164,14 +164,14 @@ public final class EUnary extends AExpression { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { if (operation == Operation.NOT) { if (tru == null && fals == null) { final Label localfals = new Label(); final Label end = new Label(); child.fals = localfals; - child.write(settings, definition, adapter); + child.write(settings, adapter); adapter.push(false); adapter.goTo(end); @@ -181,13 +181,13 @@ public final class EUnary extends AExpression { } else { child.tru = fals; child.fals = tru; - child.write(settings, definition, adapter); + child.write(settings, adapter); } } else { final org.objectweb.asm.Type type = actual.type; final Sort sort = actual.sort; - child.write(settings, definition, adapter); + child.write(settings, adapter); if (operation == Operation.BWNOT) { if (sort == Sort.DEF) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java index a8047047f93..c4026bb529e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java @@ -38,7 +38,7 @@ public final class LArrayLength extends ALink { } @Override - ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + ALink analyze(final CompilerSettings settings, final Variables variables) { if ("length".equals(value)) { if (!load) { throw new IllegalArgumentException(error("Must read array field [length].")); @@ -55,17 +55,17 @@ public final class LArrayLength extends ALink { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { adapter.arrayLength(); } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { throw new IllegalStateException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java index 045c5d0e5fa..2a8da6e1892 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java @@ -42,7 +42,7 @@ public final class LBrace extends ALink { } @Override - ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + ALink analyze(final CompilerSettings settings, final Variables variables) { if (before == null) { throw new IllegalStateException(error("Illegal tree structure.")); } @@ -51,35 +51,35 @@ public final class LBrace extends ALink { if (sort == Sort.ARRAY) { index.expected = Definition.intType; - index.analyze(settings, definition, variables); - index = index.cast(settings, definition, variables); + index.analyze(settings, variables); + index = index.cast(settings, variables); after = Definition.getType(before.struct, before.dimensions - 1); return this; } else if (sort == Sort.DEF) { - return new LDefArray(line, location, index).copy(this).analyze(settings, definition, variables); + return new LDefArray(line, location, index).copy(this).analyze(settings, variables); } else if (Map.class.isAssignableFrom(before.clazz)) { - return new LMapShortcut(line, location, index).copy(this).analyze(settings, definition, variables); + return new LMapShortcut(line, location, index).copy(this).analyze(settings, variables); } else if (List.class.isAssignableFrom(before.clazz)) { - return new LListShortcut(line, location, index).copy(this).analyze(settings, definition, variables); + return new LListShortcut(line, location, index).copy(this).analyze(settings, variables); } throw new IllegalArgumentException(error("Illegal array access on type [" + before.name + "].")); } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { - index.write(settings, definition, adapter); + void write(final CompilerSettings settings, final MethodWriter adapter) { + index.write(settings, adapter); } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { adapter.arrayLoad(after.type); } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { adapter.arrayStore(after.type); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCall.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCall.java index bd76aa293cc..150c9097ddd 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCall.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCall.java @@ -46,7 +46,7 @@ public final class LCall extends ALink { } @Override - ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + ALink analyze(final CompilerSettings settings, final Variables variables) { if (before == null) { throw new IllegalStateException(error("Illegal tree structure.")); } else if (before.sort == Definition.Sort.ARRAY) { @@ -64,8 +64,8 @@ public final class LCall extends ALink { final AExpression expression = arguments.get(argument); expression.expected = method.arguments.get(argument); - expression.analyze(settings, definition, variables); - arguments.set(argument, expression.cast(settings, definition, variables)); + expression.analyze(settings, variables); + arguments.set(argument, expression.cast(settings, variables)); } statement = true; @@ -76,7 +76,7 @@ public final class LCall extends ALink { final ALink link = new LDefCall(line, location, name, arguments); link.copy(this); - return link.analyze(settings, definition, variables); + return link.analyze(settings, variables); } throw new IllegalArgumentException(error("Unknown call [" + name + "] with [" + arguments.size() + @@ -84,14 +84,14 @@ public final class LCall extends ALink { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { for (final AExpression argument : arguments) { - argument.write(settings, definition, adapter); + argument.write(settings, adapter); } if (java.lang.reflect.Modifier.isStatic(method.reflect.getModifiers())) { @@ -108,7 +108,7 @@ public final class LCall extends ALink { } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { throw new IllegalStateException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java index 6d618eb4a26..f8a03085124 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java @@ -42,7 +42,7 @@ public final class LCast extends ALink { } @Override - ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + ALink analyze(final CompilerSettings settings, final Variables variables) { if (before == null) { throw new IllegalStateException(error("Illegal tree structure.")); } else if (store) { @@ -55,23 +55,23 @@ public final class LCast extends ALink { throw new IllegalArgumentException(error("Not a type [" + type + "].")); } - cast = AnalyzerCaster.getLegalCast(definition, location, before, after, true); + cast = AnalyzerCaster.getLegalCast(location, before, after, true); return cast != null ? this : null; } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { adapter.writeCast(cast); } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { // Do nothing. } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { throw new IllegalStateException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java index eae33809e70..842cc7c41bb 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java @@ -42,10 +42,10 @@ final class LDefArray extends ALink implements IDefLink { } @Override - ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { - index.analyze(settings, definition, variables); + ALink analyze(final CompilerSettings settings, final Variables variables) { + index.analyze(settings, variables); index.expected = index.actual; - index = index.cast(settings, definition, variables); + index = index.cast(settings, variables); after = Definition.defType; @@ -53,18 +53,18 @@ final class LDefArray extends ALink implements IDefLink { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { - index.write(settings, definition, adapter); + void write(final CompilerSettings settings, final MethodWriter adapter) { + index.write(settings, adapter); } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { final String desc = Type.getMethodDescriptor(after.type, Definition.defType.type, index.actual.type); adapter.invokeDynamic("arrayLoad", desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.ARRAY_LOAD); } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { final String desc = Type.getMethodDescriptor(Definition.voidType.type, Definition.defType.type, index.actual.type, after.type); adapter.invokeDynamic("arrayStore", desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.ARRAY_STORE); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java index 360f78eb4fd..e3b7c6c583d 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java @@ -45,13 +45,13 @@ final class LDefCall extends ALink implements IDefLink { } @Override - ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + ALink analyze(final CompilerSettings settings, final Variables variables) { for (int argument = 0; argument < arguments.size(); ++argument) { final AExpression expression = arguments.get(argument); - expression.analyze(settings, definition, variables); + expression.analyze(settings, variables); expression.expected = expression.actual; - arguments.set(argument, expression.cast(settings, definition, variables)); + arguments.set(argument, expression.cast(settings, variables)); } statement = true; @@ -61,12 +61,12 @@ final class LDefCall extends ALink implements IDefLink { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { final StringBuilder signature = new StringBuilder(); signature.append('('); @@ -77,7 +77,7 @@ final class LDefCall extends ALink implements IDefLink { // it can avoid some unnecessary boxing etc. for (final AExpression argument : arguments) { signature.append(argument.actual.type.getDescriptor()); - argument.write(settings, definition, adapter); + argument.write(settings, adapter); } signature.append(')'); @@ -88,7 +88,7 @@ final class LDefCall extends ALink implements IDefLink { } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { throw new IllegalStateException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java index af20e152c70..f54bf316254 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java @@ -43,25 +43,25 @@ final class LDefField extends ALink implements IDefLink { @Override - ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + ALink analyze(final CompilerSettings settings, final Variables variables) { after = Definition.defType; return this; } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { final String desc = Type.getMethodDescriptor(after.type, Definition.defType.type); adapter.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.LOAD); } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { final String desc = Type.getMethodDescriptor(Definition.voidType.type, Definition.defType.type, after.type); adapter.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.STORE); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LField.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LField.java index 3ec456c69a4..3c0368666d0 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LField.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LField.java @@ -46,7 +46,7 @@ public final class LField extends ALink { } @Override - ALink analyze(CompilerSettings settings, Definition definition, Variables variables) { + ALink analyze(CompilerSettings settings, Variables variables) { if (before == null) { throw new IllegalStateException(error("Illegal tree structure.")); } @@ -54,9 +54,9 @@ public final class LField extends ALink { final Sort sort = before.sort; if (sort == Sort.ARRAY) { - return new LArrayLength(line, location, value).copy(this).analyze(settings, definition, variables); + return new LArrayLength(line, location, value).copy(this).analyze(settings, variables); } else if (sort == Sort.DEF) { - return new LDefField(line, location, value).copy(this).analyze(settings, definition, variables); + return new LDefField(line, location, value).copy(this).analyze(settings, variables); } final Struct struct = before.struct; @@ -80,17 +80,17 @@ public final class LField extends ALink { Character.toUpperCase(value.charAt(0)) + value.substring(1), 1)); if (shortcut) { - return new LShortcut(line, location, value).copy(this).analyze(settings, definition, variables); + return new LShortcut(line, location, value).copy(this).analyze(settings, variables); } else { final EConstant index = new EConstant(line, location, value); - index.analyze(settings, definition, variables); + index.analyze(settings, variables); if (Map.class.isAssignableFrom(before.clazz)) { - return new LMapShortcut(line, location, index).copy(this).analyze(settings, definition, variables); + return new LMapShortcut(line, location, index).copy(this).analyze(settings, variables); } if (List.class.isAssignableFrom(before.clazz)) { - return new LListShortcut(line, location, index).copy(this).analyze(settings, definition, variables); + return new LListShortcut(line, location, index).copy(this).analyze(settings, variables); } } } @@ -99,12 +99,12 @@ public final class LField extends ALink { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { if (java.lang.reflect.Modifier.isStatic(field.reflect.getModifiers())) { adapter.getStatic(field.owner.type, field.reflect.getName(), field.type.type); } else { @@ -113,7 +113,7 @@ public final class LField extends ALink { } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { if (java.lang.reflect.Modifier.isStatic(field.reflect.getModifiers())) { adapter.putStatic(field.owner.type, field.reflect.getName(), field.type.type); } else { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java index cc20fc6dec4..1ee0f8fa3ed 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java @@ -42,7 +42,7 @@ final class LListShortcut extends ALink { } @Override - ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + ALink analyze(final CompilerSettings settings, final Variables variables) { getter = before.struct.methods.get(new Definition.MethodKey("get", 1)); setter = before.struct.methods.get(new Definition.MethodKey("set", 2)); @@ -62,8 +62,8 @@ final class LListShortcut extends ALink { if ((load || store) && (!load || getter != null) && (!store || setter != null)) { index.expected = Definition.intType; - index.analyze(settings, definition, variables); - index = index.cast(settings, definition, variables); + index.analyze(settings, variables); + index = index.cast(settings, variables); after = setter != null ? setter.arguments.get(1) : getter.rtn; } else { @@ -74,12 +74,12 @@ final class LListShortcut extends ALink { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { - index.write(settings, definition, adapter); + void write(final CompilerSettings settings, final MethodWriter adapter) { + index.write(settings, adapter); } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { if (java.lang.reflect.Modifier.isInterface(getter.owner.clazz.getModifiers())) { adapter.invokeInterface(getter.owner.type, getter.method); } else { @@ -92,7 +92,7 @@ final class LListShortcut extends ALink { } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { if (java.lang.reflect.Modifier.isInterface(setter.owner.clazz.getModifiers())) { adapter.invokeInterface(setter.owner.type, setter.method); } else { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LMapShortcut.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LMapShortcut.java index 4efbd4bdf0f..f06cb46152b 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LMapShortcut.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LMapShortcut.java @@ -42,7 +42,7 @@ final class LMapShortcut extends ALink { } @Override - ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + ALink analyze(final CompilerSettings settings, final Variables variables) { getter = before.struct.methods.get(new Definition.MethodKey("get", 1)); setter = before.struct.methods.get(new Definition.MethodKey("put", 2)); @@ -61,8 +61,8 @@ final class LMapShortcut extends ALink { if ((load || store) && (!load || getter != null) && (!store || setter != null)) { index.expected = setter != null ? setter.arguments.get(0) : getter.arguments.get(0); - index.analyze(settings, definition, variables); - index = index.cast(settings, definition, variables); + index.analyze(settings, variables); + index = index.cast(settings, variables); after = setter != null ? setter.arguments.get(1) : getter.rtn; } else { @@ -73,12 +73,12 @@ final class LMapShortcut extends ALink { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { - index.write(settings, definition, adapter); + void write(final CompilerSettings settings, final MethodWriter adapter) { + index.write(settings, adapter); } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { if (java.lang.reflect.Modifier.isInterface(getter.owner.clazz.getModifiers())) { adapter.invokeInterface(getter.owner.type, getter.method); } else { @@ -91,7 +91,7 @@ final class LMapShortcut extends ALink { } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { if (java.lang.reflect.Modifier.isInterface(setter.owner.clazz.getModifiers())) { adapter.invokeInterface(setter.owner.type, setter.method); } else { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java index 36e4b83c117..9d3e5d307fe 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java @@ -43,7 +43,7 @@ public final class LNewArray extends ALink { } @Override - ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + ALink analyze(final CompilerSettings settings, final Variables variables) { if (before != null) { throw new IllegalStateException(error("Illegal tree structure.")); } else if (store) { @@ -64,8 +64,8 @@ public final class LNewArray extends ALink { final AExpression expression = arguments.get(argument); expression.expected = Definition.intType; - expression.analyze(settings, definition, variables); - arguments.set(argument, expression.cast(settings, definition, variables)); + expression.analyze(settings, variables); + arguments.set(argument, expression.cast(settings, variables)); } after = Definition.getType(type.struct, arguments.size()); @@ -74,14 +74,14 @@ public final class LNewArray extends ALink { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { for (final AExpression argument : arguments) { - argument.write(settings, definition, adapter); + argument.write(settings, adapter); } if (arguments.size() > 1) { @@ -92,7 +92,7 @@ public final class LNewArray extends ALink { } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { throw new IllegalStateException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java index 784935e2aee..a47ced1e096 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java @@ -47,7 +47,7 @@ public final class LNewObj extends ALink { } @Override - ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + ALink analyze(final CompilerSettings settings, final Variables variables) { if (before != null) { throw new IllegalStateException(error("Illegal tree structure")); } else if (store) { @@ -78,8 +78,8 @@ public final class LNewObj extends ALink { final AExpression expression = arguments.get(argument); expression.expected = types[argument]; - expression.analyze(settings, definition, variables); - arguments.set(argument, expression.cast(settings, definition, variables)); + expression.analyze(settings, variables); + arguments.set(argument, expression.cast(settings, variables)); } statement = true; @@ -92,12 +92,12 @@ public final class LNewObj extends ALink { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { adapter.newInstance(after.type); if (load) { @@ -105,14 +105,14 @@ public final class LNewObj extends ALink { } for (final AExpression argument : arguments) { - argument.write(settings, definition, adapter); + argument.write(settings, adapter); } adapter.invokeConstructor(constructor.owner.type, constructor.method); } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { throw new IllegalStateException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LShortcut.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LShortcut.java index c65077e6e28..79feef8813b 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LShortcut.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LShortcut.java @@ -44,7 +44,7 @@ final class LShortcut extends ALink { } @Override - ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + ALink analyze(final CompilerSettings settings, final Variables variables) { final Struct struct = before.struct; getter = struct.methods.get(new Definition.MethodKey("get" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 0)); @@ -74,12 +74,12 @@ final class LShortcut extends ALink { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { if (java.lang.reflect.Modifier.isInterface(getter.owner.clazz.getModifiers())) { adapter.invokeInterface(getter.owner.type, getter.method); } else { @@ -92,7 +92,7 @@ final class LShortcut extends ALink { } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { if (java.lang.reflect.Modifier.isInterface(setter.owner.clazz.getModifiers())) { adapter.invokeInterface(setter.owner.type, setter.method); } else { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java index 91f379cce76..5fe7c22a457 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java @@ -36,7 +36,7 @@ public final class LString extends ALink { } @Override - ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + ALink analyze(final CompilerSettings settings, final Variables variables) { if (before != null) { throw new IllegalStateException("Illegal tree structure."); } else if (store) { @@ -51,17 +51,17 @@ public final class LString extends ALink { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { adapter.push(string); } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { throw new IllegalStateException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LVariable.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LVariable.java index 2c6ded3b4ec..6d4254f76ba 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LVariable.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LVariable.java @@ -43,7 +43,7 @@ public final class LVariable extends ALink { } @Override - ALink analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + ALink analyze(final CompilerSettings settings, final Variables variables) { if (before != null) { throw new IllegalStateException(error("Illegal tree structure.")); } @@ -74,17 +74,17 @@ public final class LVariable extends ALink { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void load(final CompilerSettings settings, final MethodWriter adapter) { adapter.visitVarInsn(after.type.getOpcode(Opcodes.ILOAD), slot); } @Override - void store(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void store(final CompilerSettings settings, final MethodWriter adapter) { adapter.visitVarInsn(after.type.getOpcode(Opcodes.ISTORE), slot); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBlock.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBlock.java index 802d5b6c415..7b9aed850b6 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBlock.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBlock.java @@ -20,7 +20,6 @@ package org.elasticsearch.painless.node; import org.elasticsearch.painless.CompilerSettings; -import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -41,7 +40,7 @@ public final class SBlock extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { final AStatement last = statements.get(statements.size() - 1); for (final AStatement statement : statements) { @@ -53,7 +52,7 @@ public final class SBlock extends AStatement { statement.lastSource = lastSource && statement == last; statement.lastLoop = (beginLoop || lastLoop) && statement == last; - statement.analyze(settings, definition, variables); + statement.analyze(settings, variables); methodEscape = statement.methodEscape; loopEscape = statement.loopEscape; @@ -65,11 +64,11 @@ public final class SBlock extends AStatement { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { for (final AStatement statement : statements) { statement.continu = continu; statement.brake = brake; - statement.write(settings, definition, adapter); + statement.write(settings, adapter); } } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBreak.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBreak.java index 3998b1a9ff2..08f8e811b05 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBreak.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBreak.java @@ -20,7 +20,6 @@ package org.elasticsearch.painless.node; import org.elasticsearch.painless.CompilerSettings; -import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -34,7 +33,7 @@ public final class SBreak extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { if (!inLoop) { throw new IllegalArgumentException(error("Break statement outside of a loop.")); } @@ -46,7 +45,7 @@ public final class SBreak extends AStatement { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { writeDebugInfo(adapter); adapter.goTo(brake); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SContinue.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SContinue.java index 2c4e33b6326..35317e8de8a 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SContinue.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SContinue.java @@ -20,7 +20,6 @@ package org.elasticsearch.painless.node; import org.elasticsearch.painless.CompilerSettings; -import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -34,7 +33,7 @@ public final class SContinue extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { if (!inLoop) { throw new IllegalArgumentException(error("Continue statement outside of a loop.")); } @@ -49,7 +48,7 @@ public final class SContinue extends AStatement { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { writeDebugInfo(adapter); adapter.goTo(continu); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclBlock.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclBlock.java index 5494ef9c32a..ee878146364 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclBlock.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclBlock.java @@ -20,7 +20,6 @@ package org.elasticsearch.painless.node; import org.elasticsearch.painless.CompilerSettings; -import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -41,18 +40,18 @@ public final class SDeclBlock extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { for (final SDeclaration declaration : declarations) { - declaration.analyze(settings, definition, variables); + declaration.analyze(settings, variables); } statementCount = declarations.size(); } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { for (final SDeclaration declaration : declarations) { - declaration.write(settings, definition, adapter); + declaration.write(settings, adapter); } } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java index 189ddc95936..adf24509f6c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java @@ -20,7 +20,6 @@ package org.elasticsearch.painless.node; import org.elasticsearch.painless.CompilerSettings; -import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Sort; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.Variables.Variable; @@ -47,18 +46,18 @@ public final class SDeclaration extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { variable = variables.addVariable(location, type, name, false, false); if (expression != null) { expression.expected = variable.type; - expression.analyze(settings, definition, variables); - expression = expression.cast(settings, definition, variables); + expression.analyze(settings, variables); + expression = expression.cast(settings, variables); } } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { writeDebugInfo(adapter); final org.objectweb.asm.Type type = variable.type.type; final Sort sort = variable.type.sort; @@ -66,7 +65,7 @@ public final class SDeclaration extends AStatement { final boolean initialize = expression == null; if (!initialize) { - expression.write(settings, definition, adapter); + expression.write(settings, adapter); } switch (sort) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java index 99f8b634d49..ade9f9ba221 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java @@ -41,21 +41,21 @@ public final class SDo extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { variables.incrementScope(); block.beginLoop = true; block.inLoop = true; - block.analyze(settings, definition, variables); + block.analyze(settings, variables); if (block.loopEscape && !block.anyContinue) { throw new IllegalArgumentException(error("Extraneous do while loop.")); } condition.expected = Definition.booleanType; - condition.analyze(settings, definition, variables); - condition = condition.cast(settings, definition, variables); + condition.analyze(settings, variables); + condition = condition.cast(settings, variables); if (condition.constant != null) { final boolean continuous = (boolean)condition.constant; @@ -80,7 +80,7 @@ public final class SDo extends AStatement { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { writeDebugInfo(adapter); final Label start = new Label(); final Label begin = new Label(); @@ -90,12 +90,12 @@ public final class SDo extends AStatement { block.continu = begin; block.brake = end; - block.write(settings, definition, adapter); + block.write(settings, adapter); adapter.mark(begin); condition.fals = end; - condition.write(settings, definition, adapter); + condition.write(settings, adapter); adapter.writeLoopCounter(loopCounterSlot, Math.max(1, block.statementCount)); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java index 2ed0d10b930..1f107548dff 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java @@ -39,9 +39,9 @@ public final class SExpression extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { expression.read = lastSource; - expression.analyze(settings, definition, variables); + expression.analyze(settings, variables); if (!lastSource && !expression.statement) { throw new IllegalArgumentException(error("Not a statement.")); @@ -50,7 +50,7 @@ public final class SExpression extends AStatement { final boolean rtn = lastSource && expression.actual.sort != Sort.VOID; expression.expected = rtn ? Definition.objectType : expression.actual; - expression = expression.cast(settings, definition, variables); + expression = expression.cast(settings, variables); methodEscape = rtn; loopEscape = rtn; @@ -59,9 +59,9 @@ public final class SExpression extends AStatement { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { writeDebugInfo(adapter); - expression.write(settings, definition, adapter); + expression.write(settings, adapter); if (methodEscape) { adapter.returnValue(); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java index ef97fbac06b..ae59382039d 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java @@ -46,19 +46,19 @@ public final class SFor extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { variables.incrementScope(); boolean continuous = false; if (initializer != null) { if (initializer instanceof SDeclBlock) { - ((SDeclBlock)initializer).analyze(settings, definition, variables); + ((SDeclBlock)initializer).analyze(settings, variables); } else if (initializer instanceof AExpression) { final AExpression initializer = (AExpression)this.initializer; initializer.read = false; - initializer.analyze(settings, definition, variables); + initializer.analyze(settings, variables); if (!initializer.statement) { throw new IllegalArgumentException(initializer.error("Not a statement.")); @@ -71,8 +71,8 @@ public final class SFor extends AStatement { if (condition != null) { condition.expected = Definition.booleanType; - condition.analyze(settings, definition, variables); - condition = condition.cast(settings, definition, variables); + condition.analyze(settings, variables); + condition = condition.cast(settings, variables); if (condition.constant != null) { continuous = (boolean)condition.constant; @@ -91,7 +91,7 @@ public final class SFor extends AStatement { if (afterthought != null) { afterthought.read = false; - afterthought.analyze(settings, definition, variables); + afterthought.analyze(settings, variables); if (!afterthought.statement) { throw new IllegalArgumentException(afterthought.error("Not a statement.")); @@ -104,7 +104,7 @@ public final class SFor extends AStatement { block.beginLoop = true; block.inLoop = true; - block.analyze(settings, definition, variables); + block.analyze(settings, variables); if (block.loopEscape && !block.anyContinue) { throw new IllegalArgumentException(error("Extraneous for loop.")); @@ -128,18 +128,18 @@ public final class SFor extends AStatement { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { writeDebugInfo(adapter); final Label start = new Label(); final Label begin = afterthought == null ? start : new Label(); final Label end = new Label(); if (initializer instanceof SDeclBlock) { - ((SDeclBlock)initializer).write(settings, definition, adapter); + ((SDeclBlock)initializer).write(settings, adapter); } else if (initializer instanceof AExpression) { AExpression initializer = (AExpression)this.initializer; - initializer.write(settings, definition, adapter); + initializer.write(settings, adapter); adapter.writePop(initializer.expected.sort.size); } @@ -147,7 +147,7 @@ public final class SFor extends AStatement { if (condition != null) { condition.fals = end; - condition.write(settings, definition, adapter); + condition.write(settings, adapter); } boolean allEscape = false; @@ -162,14 +162,14 @@ public final class SFor extends AStatement { } adapter.writeLoopCounter(loopCounterSlot, statementCount); - block.write(settings, definition, adapter); + block.write(settings, adapter); } else { adapter.writeLoopCounter(loopCounterSlot, 1); } if (afterthought != null) { adapter.mark(begin); - afterthought.write(settings, definition, adapter); + afterthought.write(settings, adapter); } if (afterthought != null || !allEscape) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java index 34f4a80645c..40c20a1cb87 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java @@ -44,10 +44,10 @@ public final class SIfElse extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { condition.expected = Definition.booleanType; - condition.analyze(settings, definition, variables); - condition = condition.cast(settings, definition, variables); + condition.analyze(settings, variables); + condition = condition.cast(settings, variables); if (condition.constant != null) { throw new IllegalArgumentException(error("Extraneous if statement.")); @@ -58,7 +58,7 @@ public final class SIfElse extends AStatement { ifblock.lastLoop = lastLoop; variables.incrementScope(); - ifblock.analyze(settings, definition, variables); + ifblock.analyze(settings, variables); variables.decrementScope(); anyContinue = ifblock.anyContinue; @@ -71,7 +71,7 @@ public final class SIfElse extends AStatement { elseblock.lastLoop = lastLoop; variables.incrementScope(); - elseblock.analyze(settings, definition, variables); + elseblock.analyze(settings, variables); variables.decrementScope(); methodEscape = ifblock.methodEscape && elseblock.methodEscape; @@ -84,17 +84,17 @@ public final class SIfElse extends AStatement { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { writeDebugInfo(adapter); final Label end = new Label(); final Label fals = elseblock != null ? new Label() : end; condition.fals = fals; - condition.write(settings, definition, adapter); + condition.write(settings, adapter); ifblock.continu = continu; ifblock.brake = brake; - ifblock.write(settings, definition, adapter); + ifblock.write(settings, adapter); if (elseblock != null) { if (!ifblock.allEscape) { @@ -105,7 +105,7 @@ public final class SIfElse extends AStatement { elseblock.continu = continu; elseblock.brake = brake; - elseblock.write(settings, definition, adapter); + elseblock.write(settings, adapter); } adapter.mark(end); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java index 4442e5b9ee4..4caf57f463b 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java @@ -38,10 +38,10 @@ public final class SReturn extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { expression.expected = Definition.objectType; - expression.analyze(settings, definition, variables); - expression = expression.cast(settings, definition, variables); + expression.analyze(settings, variables); + expression = expression.cast(settings, variables); methodEscape = true; loopEscape = true; @@ -51,9 +51,9 @@ public final class SReturn extends AStatement { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { writeDebugInfo(adapter); - expression.write(settings, definition, adapter); + expression.write(settings, adapter); adapter.returnValue(); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSource.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSource.java index e5a80802ce8..e77ce8330a6 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSource.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSource.java @@ -20,7 +20,6 @@ package org.elasticsearch.painless.node; import org.elasticsearch.painless.CompilerSettings; -import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.objectweb.asm.Opcodes; import org.elasticsearch.painless.MethodWriter; @@ -42,7 +41,7 @@ public final class SSource extends AStatement { } @Override - public void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + public void analyze(final CompilerSettings settings, final Variables variables) { variables.incrementScope(); final AStatement last = statements.get(statements.size() - 1); @@ -53,7 +52,7 @@ public final class SSource extends AStatement { } statement.lastSource = statement == last; - statement.analyze(settings, definition, variables); + statement.analyze(settings, variables); methodEscape = statement.methodEscape; allEscape = statement.allEscape; @@ -63,9 +62,9 @@ public final class SSource extends AStatement { } @Override - public void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + public void write(final CompilerSettings settings, final MethodWriter adapter) { for (final AStatement statement : statements) { - statement.write(settings, definition, adapter); + statement.write(settings, adapter); } if (!methodEscape) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java index 99fb5c6a973..8a2909d0a3b 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java @@ -38,10 +38,10 @@ public final class SThrow extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { expression.expected = Definition.exceptionType; - expression.analyze(settings, definition, variables); - expression = expression.cast(settings, definition, variables); + expression.analyze(settings, variables); + expression = expression.cast(settings, variables); methodEscape = true; loopEscape = true; @@ -50,9 +50,9 @@ public final class SThrow extends AStatement { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { writeDebugInfo(adapter); - expression.write(settings, definition, adapter); + expression.write(settings, adapter); adapter.throwException(); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STrap.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STrap.java index acb50a2b962..a1ee15a050f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STrap.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STrap.java @@ -20,7 +20,6 @@ package org.elasticsearch.painless.node; import org.elasticsearch.painless.CompilerSettings; -import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.Variables.Variable; import org.objectweb.asm.Label; @@ -51,7 +50,7 @@ public final class STrap extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { variable = variables.addVariable(location, type, name, true, false); if (!Exception.class.isAssignableFrom(variable.type.clazz)) { @@ -63,7 +62,7 @@ public final class STrap extends AStatement { block.inLoop = inLoop; block.lastLoop = lastLoop; - block.analyze(settings, definition, variables); + block.analyze(settings, variables); methodEscape = block.methodEscape; loopEscape = block.loopEscape; @@ -75,7 +74,7 @@ public final class STrap extends AStatement { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { writeDebugInfo(adapter); final Label jump = new Label(); @@ -85,7 +84,7 @@ public final class STrap extends AStatement { if (block != null) { block.continu = continu; block.brake = brake; - block.write(settings, definition, adapter); + block.write(settings, adapter); } adapter.visitTryCatchBlock(begin, end, jump, variable.type.type.getInternalName()); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STry.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STry.java index 0329826b02a..70a5b2164da 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STry.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STry.java @@ -20,7 +20,6 @@ package org.elasticsearch.painless.node; import org.elasticsearch.painless.CompilerSettings; -import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.objectweb.asm.Label; import org.elasticsearch.painless.MethodWriter; @@ -44,13 +43,13 @@ public final class STry extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { block.lastSource = lastSource; block.inLoop = inLoop; block.lastLoop = lastLoop; variables.incrementScope(); - block.analyze(settings, definition, variables); + block.analyze(settings, variables); variables.decrementScope(); methodEscape = block.methodEscape; @@ -67,7 +66,7 @@ public final class STry extends AStatement { trap.lastLoop = lastLoop; variables.incrementScope(); - trap.analyze(settings, definition, variables); + trap.analyze(settings, variables); variables.decrementScope(); methodEscape &= trap.methodEscape; @@ -83,7 +82,7 @@ public final class STry extends AStatement { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { writeDebugInfo(adapter); final Label begin = new Label(); final Label end = new Label(); @@ -93,7 +92,7 @@ public final class STry extends AStatement { block.continu = continu; block.brake = brake; - block.write(settings, definition, adapter); + block.write(settings, adapter); if (!block.allEscape) { adapter.goTo(exception); @@ -105,7 +104,7 @@ public final class STry extends AStatement { trap.begin = begin; trap.end = end; trap.exception = traps.size() > 1 ? exception : null; - trap.write(settings, definition, adapter); + trap.write(settings, adapter); } if (!block.allEscape || traps.size() > 1) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java index 83afe469320..a6d88fdcced 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java @@ -41,12 +41,12 @@ public final class SWhile extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Definition definition, final Variables variables) { + void analyze(final CompilerSettings settings, final Variables variables) { variables.incrementScope(); condition.expected = Definition.booleanType; - condition.analyze(settings, definition, variables); - condition = condition.cast(settings, definition, variables); + condition.analyze(settings, variables); + condition = condition.cast(settings, variables); boolean continuous = false; @@ -68,7 +68,7 @@ public final class SWhile extends AStatement { block.beginLoop = true; block.inLoop = true; - block.analyze(settings, definition, variables); + block.analyze(settings, variables); if (block.loopEscape && !block.anyContinue) { throw new IllegalArgumentException(error("Extranous while loop.")); @@ -92,7 +92,7 @@ public final class SWhile extends AStatement { } @Override - void write(final CompilerSettings settings, final Definition definition, final MethodWriter adapter) { + void write(final CompilerSettings settings, final MethodWriter adapter) { writeDebugInfo(adapter); final Label begin = new Label(); final Label end = new Label(); @@ -100,14 +100,14 @@ public final class SWhile extends AStatement { adapter.mark(begin); condition.fals = end; - condition.write(settings, definition, adapter); + condition.write(settings, adapter); if (block != null) { adapter.writeLoopCounter(loopCounterSlot, Math.max(1, block.statementCount)); block.continu = begin; block.brake = end; - block.write(settings, definition, adapter); + block.write(settings, adapter); } else { adapter.writeLoopCounter(loopCounterSlot, 1); } From 6205f79554933bb1f10266d8b04c98c0841cc2a7 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Fri, 20 May 2016 14:03:46 +0200 Subject: [PATCH 15/22] Remove Definitions's copy-ctor; fix RuntimeClass to be unmodifiable Please note: The maps inside the pirvate singleton instance of Defininition are no longer unmodifiable, but nothing from the outside can modify it! All private :-) --- .../elasticsearch/painless/Definition.java | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java index 0a81188e776..5c45aaaf407 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java @@ -40,8 +40,7 @@ public final class Definition { private static final String DEFINITION_FILE = "definition.txt"; - // The second construction is used to finalize all the variables, so there is no mistake of modification afterwards. - private static final Definition INSTANCE = new Definition(new Definition()); + private static final Definition INSTANCE = new Definition(); /** Some native types as constants: */ public static final Type voidType = getType("void"); @@ -293,7 +292,7 @@ public final class Definition { staticMembers = new HashMap<>(); members = new HashMap<>(); } - + private Struct(final Struct struct) { name = struct.name; clazz = struct.clazz; @@ -307,6 +306,10 @@ public final class Definition { members = Collections.unmodifiableMap(struct.members); } + private Struct freeze() { + return new Struct(this); + } + @Override public boolean equals(Object object) { if (this == object) { @@ -385,9 +388,9 @@ public final class Definition { private RuntimeClass(final Map methods, final Map getters, final Map setters) { - this.methods = methods; - this.getters = getters; - this.setters = setters; + this.methods = Collections.unmodifiableMap(methods); + this.getters = Collections.unmodifiableMap(getters); + this.setters = Collections.unmodifiableMap(setters); } } @@ -436,19 +439,10 @@ public final class Definition { for (Struct struct : structsMap.values()) { addRuntimeClass(struct); } - } - - private Definition(final Definition definition) { - final Map structs = new HashMap<>(); - - for (final Struct struct : definition.structsMap.values()) { - structs.put(struct.name, new Struct(struct)); + // copy all structs to make them unmodifiable for outside users: + for (final Map.Entry entry : structsMap.entrySet()) { + entry.setValue(entry.getValue().freeze()); } - - this.structsMap = Collections.unmodifiableMap(structs); - this.transformsMap = Collections.unmodifiableMap(definition.transformsMap); - this.runtimeMap = Collections.unmodifiableMap(definition.runtimeMap); - this.simpleTypesMap = Collections.unmodifiableMap(definition.simpleTypesMap); } /** adds classes from definition. returns hierarchy */ From 7bc91c00d9329268ac5bb612f442d74fcf04ae73 Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Fri, 20 May 2016 14:12:15 +0200 Subject: [PATCH 16/22] More elegant way to force class initialization --- .../java/org/elasticsearch/painless/PainlessPlugin.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java index de774344ee2..7533707cf63 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java @@ -30,14 +30,9 @@ import org.elasticsearch.script.ScriptModule; */ public final class PainlessPlugin extends Plugin { - // parse our definition at startup (not on the user's first script) - // compilation process is sandboxed and has no file access. + // force to pare our definition at startup (not on the user's first script) static { - try { - Class.forName("org.elasticsearch.painless.Definition"); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } + Definition.voidType.hashCode(); } @Override From b3c71c1e3ad8b3c2516b0898dbaa696b69cb7abb Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Fri, 20 May 2016 08:42:29 -0400 Subject: [PATCH 17/22] improve style for these constants --- .../painless/AnalyzerCaster.java | 96 +++++++++---------- .../elasticsearch/painless/Definition.java | 46 ++++----- .../elasticsearch/painless/MethodWriter.java | 22 ++--- .../painless/PainlessPlugin.java | 2 +- .../elasticsearch/painless/node/EBinary.java | 6 +- .../elasticsearch/painless/node/EBool.java | 6 +- .../elasticsearch/painless/node/EBoolean.java | 2 +- .../elasticsearch/painless/node/EChain.java | 6 +- .../elasticsearch/painless/node/EComp.java | 32 +++---- .../painless/node/EConditional.java | 2 +- .../painless/node/EConstant.java | 18 ++-- .../elasticsearch/painless/node/EDecimal.java | 4 +- .../elasticsearch/painless/node/ENull.java | 2 +- .../elasticsearch/painless/node/ENumeric.java | 14 +-- .../elasticsearch/painless/node/EUnary.java | 8 +- .../painless/node/LArrayLength.java | 2 +- .../elasticsearch/painless/node/LBrace.java | 2 +- .../painless/node/LDefArray.java | 6 +- .../elasticsearch/painless/node/LDefCall.java | 4 +- .../painless/node/LDefField.java | 6 +- .../painless/node/LListShortcut.java | 2 +- .../painless/node/LNewArray.java | 2 +- .../elasticsearch/painless/node/LString.java | 2 +- .../org/elasticsearch/painless/node/SDo.java | 2 +- .../painless/node/SExpression.java | 2 +- .../org/elasticsearch/painless/node/SFor.java | 2 +- .../elasticsearch/painless/node/SIfElse.java | 2 +- .../elasticsearch/painless/node/SReturn.java | 2 +- .../elasticsearch/painless/node/SThrow.java | 2 +- .../elasticsearch/painless/node/SWhile.java | 2 +- 30 files changed, 153 insertions(+), 153 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java index 2495d2edacd..da7debb7e05 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/AnalyzerCaster.java @@ -118,18 +118,18 @@ public final class AnalyzerCaster { final Sort sort = from.sort; if (sort == Sort.DEF) { - return Definition.defType; + return Definition.DEF_TYPE; } else if ((sort == Sort.DOUBLE || sort == Sort.DOUBLE_OBJ) && decimal) { - return primitive ? Definition.doubleType : Definition.doubleobjType; + return primitive ? Definition.DOUBLE_TYPE : Definition.DOUBLE_OBJ_TYPE; } else if ((sort == Sort.FLOAT || sort == Sort.FLOAT_OBJ) && decimal) { - return primitive ? Definition.floatType : Definition.floatobjType; + return primitive ? Definition.FLOAT_TYPE : Definition.FLOAT_OBJ_TYPE; } else if (sort == Sort.LONG || sort == Sort.LONG_OBJ) { - return primitive ? Definition.longType : Definition.longobjType; + return primitive ? Definition.LONG_TYPE : Definition.LONG_OBJ_TYPE; } else if (sort == Sort.INT || sort == Sort.INT_OBJ || sort == Sort.CHAR || sort == Sort.CHAR_OBJ || sort == Sort.SHORT || sort == Sort.SHORT_OBJ || sort == Sort.BYTE || sort == Sort.BYTE_OBJ) { - return primitive ? Definition.intType : Definition.intobjType; + return primitive ? Definition.INT_TYPE : Definition.INT_OBJ_TYPE; } return null; @@ -140,21 +140,21 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.DEF || sort1 == Sort.DEF) { - return Definition.defType; + return Definition.DEF_TYPE; } if (decimal) { if (sort0 == Sort.DOUBLE || sort0 == Sort.DOUBLE_OBJ || sort1 == Sort.DOUBLE || sort1 == Sort.DOUBLE_OBJ) { - return primitive ? Definition.doubleType : Definition.doubleobjType; + return primitive ? Definition.DOUBLE_TYPE : Definition.DOUBLE_OBJ_TYPE; } else if (sort0 == Sort.FLOAT || sort0 == Sort.FLOAT_OBJ || sort1 == Sort.FLOAT || sort1 == Sort.FLOAT_OBJ) { - return primitive ? Definition.floatType : Definition.floatobjType; + return primitive ? Definition.FLOAT_TYPE : Definition.FLOAT_OBJ_TYPE; } } if (sort0 == Sort.LONG || sort0 == Sort.LONG_OBJ || sort1 == Sort.LONG || sort1 == Sort.LONG_OBJ) { - return primitive ? Definition.longType : Definition.longobjType; + return primitive ? Definition.LONG_TYPE : Definition.LONG_OBJ_TYPE; } else if (sort0 == Sort.INT || sort0 == Sort.INT_OBJ || sort1 == Sort.INT || sort1 == Sort.INT_OBJ || sort0 == Sort.CHAR || sort0 == Sort.CHAR_OBJ || @@ -163,7 +163,7 @@ public final class AnalyzerCaster { sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ || sort0 == Sort.BYTE || sort0 == Sort.BYTE_OBJ || sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { - return primitive ? Definition.intType : Definition.intobjType; + return primitive ? Definition.INT_TYPE : Definition.INT_OBJ_TYPE; } return null; @@ -174,7 +174,7 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.STRING || sort1 == Sort.STRING) { - return Definition.stringType; + return Definition.STRING_TYPE; } return promoteNumeric(from0, from1, true, true); @@ -185,7 +185,7 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0.bool || sort1.bool) { - return Definition.booleanType; + return Definition.BOOLEAN_TYPE; } return promoteNumeric(from0, from1, false, true); @@ -196,20 +196,20 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.DEF || sort1 == Sort.DEF) { - return Definition.defType; + return Definition.DEF_TYPE; } final boolean primitive = sort0.primitive && sort1.primitive; if (sort0.bool && sort1.bool) { - return primitive ? Definition.booleanType : Definition.booleanobjType; + return primitive ? Definition.BOOLEAN_TYPE : Definition.BOOLEAN_OBJ_TYPE; } if (sort0.numeric && sort1.numeric) { return promoteNumeric(from0, from1, true, primitive); } - return Definition.objectType; + return Definition.OBJECT_TYPE; } public static Type promoteReference(final Type from0, final Type from1) { @@ -217,12 +217,12 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.DEF || sort1 == Sort.DEF) { - return Definition.defType; + return Definition.DEF_TYPE; } if (sort0.primitive && sort1.primitive) { if (sort0.bool && sort1.bool) { - return Definition.booleanType; + return Definition.BOOLEAN_TYPE; } if (sort0.numeric && sort1.numeric) { @@ -230,7 +230,7 @@ public final class AnalyzerCaster { } } - return Definition.objectType; + return Definition.OBJECT_TYPE; } public static Type promoteConditional(final Type from0, final Type from1, final Object const0, final Object const1) { @@ -242,48 +242,48 @@ public final class AnalyzerCaster { final Sort sort1 = from1.sort; if (sort0 == Sort.DEF || sort1 == Sort.DEF) { - return Definition.defType; + return Definition.DEF_TYPE; } final boolean primitive = sort0.primitive && sort1.primitive; if (sort0.bool && sort1.bool) { - return primitive ? Definition.booleanType : Definition.booleanobjType; + return primitive ? Definition.BOOLEAN_TYPE : Definition.BOOLEAN_OBJ_TYPE; } if (sort0.numeric && sort1.numeric) { if (sort0 == Sort.DOUBLE || sort0 == Sort.DOUBLE_OBJ || sort1 == Sort.DOUBLE || sort1 == Sort.DOUBLE_OBJ) { - return primitive ? Definition.doubleType : Definition.doubleobjType; + return primitive ? Definition.DOUBLE_TYPE : Definition.DOUBLE_OBJ_TYPE; } else if (sort0 == Sort.FLOAT || sort0 == Sort.FLOAT_OBJ || sort1 == Sort.FLOAT || sort1 == Sort.FLOAT_OBJ) { - return primitive ? Definition.floatType : Definition.floatobjType; + return primitive ? Definition.FLOAT_TYPE : Definition.FLOAT_OBJ_TYPE; } else if (sort0 == Sort.LONG || sort0 == Sort.LONG_OBJ || sort1 == Sort.LONG || sort1 == Sort.LONG_OBJ) { - return sort0.primitive && sort1.primitive ? Definition.longType : Definition.longobjType; + return sort0.primitive && sort1.primitive ? Definition.LONG_TYPE : Definition.LONG_OBJ_TYPE; } else { if (sort0 == Sort.BYTE || sort0 == Sort.BYTE_OBJ) { if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { - return primitive ? Definition.byteType : Definition.byteobjType; + return primitive ? Definition.BYTE_TYPE : Definition.BYTE_OBJ_TYPE; } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { if (const1 != null) { final short constant = (short)const1; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? Definition.byteType : Definition.byteobjType; + return primitive ? Definition.BYTE_TYPE : Definition.BYTE_OBJ_TYPE; } } - return primitive ? Definition.shortType : Definition.shortobjType; + return primitive ? Definition.SHORT_TYPE : Definition.SHORT_OBJ_TYPE; } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { - return primitive ? Definition.intType : Definition.intobjType; + return primitive ? Definition.INT_TYPE : Definition.INT_OBJ_TYPE; } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { if (const1 != null) { final int constant = (int)const1; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? Definition.byteType : Definition.byteobjType; + return primitive ? Definition.BYTE_TYPE : Definition.BYTE_OBJ_TYPE; } } - return primitive ? Definition.intType : Definition.intobjType; + return primitive ? Definition.INT_TYPE : Definition.INT_OBJ_TYPE; } } else if (sort0 == Sort.SHORT || sort0 == Sort.SHORT_OBJ) { if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { @@ -291,43 +291,43 @@ public final class AnalyzerCaster { final short constant = (short)const0; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? Definition.byteType : Definition.byteobjType; + return primitive ? Definition.BYTE_TYPE : Definition.BYTE_OBJ_TYPE; } } - return primitive ? Definition.shortType : Definition.shortobjType; + return primitive ? Definition.SHORT_TYPE : Definition.SHORT_OBJ_TYPE; } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { - return primitive ? Definition.shortType : Definition.shortobjType; + return primitive ? Definition.SHORT_TYPE : Definition.SHORT_OBJ_TYPE; } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { - return primitive ? Definition.intType : Definition.intobjType; + return primitive ? Definition.INT_TYPE : Definition.INT_OBJ_TYPE; } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { if (const1 != null) { final int constant = (int)const1; if (constant <= Short.MAX_VALUE && constant >= Short.MIN_VALUE) { - return primitive ? Definition.shortType : Definition.shortobjType; + return primitive ? Definition.SHORT_TYPE : Definition.SHORT_OBJ_TYPE; } } - return primitive ? Definition.intType : Definition.intobjType; + return primitive ? Definition.INT_TYPE : Definition.INT_OBJ_TYPE; } } else if (sort0 == Sort.CHAR || sort0 == Sort.CHAR_OBJ) { if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { - return primitive ? Definition.intType : Definition.intobjType; + return primitive ? Definition.INT_TYPE : Definition.INT_OBJ_TYPE; } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { - return primitive ? Definition.intType : Definition.intobjType; + return primitive ? Definition.INT_TYPE : Definition.INT_OBJ_TYPE; } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { - return primitive ? Definition.charType : Definition.charobjType; + return primitive ? Definition.CHAR_TYPE : Definition.CHAR_OBJ_TYPE; } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { if (const1 != null) { final int constant = (int)const1; if (constant <= Character.MAX_VALUE && constant >= Character.MIN_VALUE) { - return primitive ? Definition.byteType : Definition.byteobjType; + return primitive ? Definition.BYTE_TYPE : Definition.BYTE_OBJ_TYPE; } } - return primitive ? Definition.intType : Definition.intobjType; + return primitive ? Definition.INT_TYPE : Definition.INT_OBJ_TYPE; } } else if (sort0 == Sort.INT || sort0 == Sort.INT_OBJ) { if (sort1 == Sort.BYTE || sort1 == Sort.BYTE_OBJ) { @@ -335,33 +335,33 @@ public final class AnalyzerCaster { final int constant = (int)const0; if (constant <= Byte.MAX_VALUE && constant >= Byte.MIN_VALUE) { - return primitive ? Definition.byteType : Definition.byteobjType; + return primitive ? Definition.BYTE_TYPE : Definition.BYTE_OBJ_TYPE; } } - return primitive ? Definition.intType : Definition.intobjType; + return primitive ? Definition.INT_TYPE : Definition.INT_OBJ_TYPE; } else if (sort1 == Sort.SHORT || sort1 == Sort.SHORT_OBJ) { if (const0 != null) { final int constant = (int)const0; if (constant <= Short.MAX_VALUE && constant >= Short.MIN_VALUE) { - return primitive ? Definition.byteType : Definition.byteobjType; + return primitive ? Definition.BYTE_TYPE : Definition.BYTE_OBJ_TYPE; } } - return primitive ? Definition.intType : Definition.intobjType; + return primitive ? Definition.INT_TYPE : Definition.INT_OBJ_TYPE; } else if (sort1 == Sort.CHAR || sort1 == Sort.CHAR_OBJ) { if (const0 != null) { final int constant = (int)const0; if (constant <= Character.MAX_VALUE && constant >= Character.MIN_VALUE) { - return primitive ? Definition.byteType : Definition.byteobjType; + return primitive ? Definition.BYTE_TYPE : Definition.BYTE_OBJ_TYPE; } } - return primitive ? Definition.intType : Definition.intobjType; + return primitive ? Definition.INT_TYPE : Definition.INT_OBJ_TYPE; } else if (sort1 == Sort.INT || sort1 == Sort.INT_OBJ) { - return primitive ? Definition.intType : Definition.intobjType; + return primitive ? Definition.INT_TYPE : Definition.INT_OBJ_TYPE; } } } @@ -371,7 +371,7 @@ public final class AnalyzerCaster { // to calculate the highest upper bound for the two types and return that. // However, for now we just return objectType that may require an extra cast. - return Definition.objectType; + return Definition.OBJECT_TYPE; } private AnalyzerCaster() {} diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java index 5c45aaaf407..9e665e8280f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Definition.java @@ -43,29 +43,29 @@ public final class Definition { private static final Definition INSTANCE = new Definition(); /** Some native types as constants: */ - public static final Type voidType = getType("void"); - public static final Type booleanType = getType("boolean"); - public static final Type booleanobjType = getType("Boolean"); - public static final Type byteType = getType("byte"); - public static final Type byteobjType = getType("Byte"); - public static final Type shortType = getType("short"); - public static final Type shortobjType = getType("Short"); - public static final Type intType = getType("int"); - public static final Type intobjType = getType("Integer"); - public static final Type longType = getType("long"); - public static final Type longobjType = getType("Long"); - public static final Type floatType = getType("float"); - public static final Type floatobjType = getType("Float"); - public static final Type doubleType = getType("double"); - public static final Type doubleobjType = getType("Double"); - public static final Type charType = getType("char"); - public static final Type charobjType = getType("Character"); - public static final Type objectType = getType("Object"); - public static final Type defType = getType("def"); - public static final Type defobjType = getType("Def"); - public static final Type stringType = getType("String"); - public static final Type exceptionType = getType("Exception"); - public static final Type utilityType = getType("Utility"); + public static final Type VOID_TYPE = getType("void"); + public static final Type BOOLEAN_TYPE = getType("boolean"); + public static final Type BOOLEAN_OBJ_TYPE = getType("Boolean"); + public static final Type BYTE_TYPE = getType("byte"); + public static final Type BYTE_OBJ_TYPE = getType("Byte"); + public static final Type SHORT_TYPE = getType("short"); + public static final Type SHORT_OBJ_TYPE = getType("Short"); + public static final Type INT_TYPE = getType("int"); + public static final Type INT_OBJ_TYPE = getType("Integer"); + public static final Type LONG_TYPE = getType("long"); + public static final Type LONG_OBJ_TYPE = getType("Long"); + public static final Type FLOAT_TYPE = getType("float"); + public static final Type FLOAT_OBJ_TYPE = getType("Float"); + public static final Type DOUBLE_TYPE = getType("double"); + public static final Type DOUBLE_OBJ_TYPE = getType("Double"); + public static final Type CHAR_TYPE = getType("char"); + public static final Type CHAR_OBJ_TYPE = getType("Character"); + public static final Type OBJECT_TYPE = getType("Object"); + public static final Type DEF_TYPE = getType("def"); + public static final Type DEF_UTIL_TYPE = getType("Def"); + public static final Type STRING_TYPE = getType("String"); + public static final Type EXCEPTION_TYPE = getType("Exception"); + public static final Type UTILITY_TYPE = getType("Utility"); public enum Sort { VOID( void.class , 0 , true , false , false , false ), diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java index cddd1326c74..ebc7d7b9f61 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java @@ -212,17 +212,17 @@ public final class MethodWriter extends GeneratorAdapter { if (sort == Sort.DEF) { switch (operation) { - case MUL: invokeStatic(Definition.defobjType.type, DEF_MUL_CALL); break; - case DIV: invokeStatic(Definition.defobjType.type, DEF_DIV_CALL); break; - case REM: invokeStatic(Definition.defobjType.type, DEF_REM_CALL); break; - case ADD: invokeStatic(Definition.defobjType.type, DEF_ADD_CALL); break; - case SUB: invokeStatic(Definition.defobjType.type, DEF_SUB_CALL); break; - case LSH: invokeStatic(Definition.defobjType.type, DEF_LSH_CALL); break; - case USH: invokeStatic(Definition.defobjType.type, DEF_RSH_CALL); break; - case RSH: invokeStatic(Definition.defobjType.type, DEF_USH_CALL); break; - case BWAND: invokeStatic(Definition.defobjType.type, DEF_AND_CALL); break; - case XOR: invokeStatic(Definition.defobjType.type, DEF_XOR_CALL); break; - case BWOR: invokeStatic(Definition.defobjType.type, DEF_OR_CALL); break; + case MUL: invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_MUL_CALL); break; + case DIV: invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_DIV_CALL); break; + case REM: invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_REM_CALL); break; + case ADD: invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_ADD_CALL); break; + case SUB: invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_SUB_CALL); break; + case LSH: invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_LSH_CALL); break; + case USH: invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_RSH_CALL); break; + case RSH: invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_USH_CALL); break; + case BWAND: invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_AND_CALL); break; + case XOR: invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_XOR_CALL); break; + case BWOR: invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_OR_CALL); break; default: throw new IllegalStateException("Error " + location + ": Illegal tree structure."); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java index 7533707cf63..8f116c3c6f7 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/PainlessPlugin.java @@ -32,7 +32,7 @@ public final class PainlessPlugin extends Plugin { // force to pare our definition at startup (not on the user's first script) static { - Definition.voidType.hashCode(); + Definition.VOID_TYPE.hashCode(); } @Override diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java index 38871d007f4..0046d498074 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java @@ -284,7 +284,7 @@ public final class EBinary extends AExpression { } left.expected = promote; - right.expected = Definition.intType; + right.expected = Definition.INT_TYPE; right.explicit = true; left = left.cast(settings, variables); @@ -317,7 +317,7 @@ public final class EBinary extends AExpression { } left.expected = promote; - right.expected = Definition.intType; + right.expected = Definition.INT_TYPE; right.explicit = true; left = left.cast(settings, variables); @@ -350,7 +350,7 @@ public final class EBinary extends AExpression { } left.expected = promote; - right.expected = Definition.intType; + right.expected = Definition.INT_TYPE; right.explicit = true; left = left.cast(settings, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java index 28072b9d9bd..1e2af41c0c0 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java @@ -45,11 +45,11 @@ public final class EBool extends AExpression { @Override void analyze(final CompilerSettings settings, final Variables variables) { - left.expected = Definition.booleanType; + left.expected = Definition.BOOLEAN_TYPE; left.analyze(settings, variables); left = left.cast(settings, variables); - right.expected = Definition.booleanType; + right.expected = Definition.BOOLEAN_TYPE; right.analyze(settings, variables); right = right.cast(settings, variables); @@ -63,7 +63,7 @@ public final class EBool extends AExpression { } } - actual = Definition.booleanType; + actual = Definition.BOOLEAN_TYPE; } @Override diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java index 979fbed03e3..2e019c576e0 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java @@ -37,7 +37,7 @@ public final class EBoolean extends AExpression { @Override void analyze(final CompilerSettings settings, final Variables variables) { - actual = Definition.booleanType; + actual = Definition.BOOLEAN_TYPE; } @Override diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java index d992edd8505..2f8ad66f101 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java @@ -199,7 +199,7 @@ public final class EChain extends AExpression { expression.expected = expression.actual; } else if (operation == Operation.LSH || operation == Operation.RSH || operation == Operation.USH) { - expression.expected = Definition.intType; + expression.expected = Definition.INT_TYPE; expression.explicit = true; } else { expression.expected = promote; @@ -211,7 +211,7 @@ public final class EChain extends AExpression { back = AnalyzerCaster.getLegalCast(location, promote, last.after, true); this.statement = true; - this.actual = read ? last.after : Definition.voidType; + this.actual = read ? last.after : Definition.VOID_TYPE; } private void analyzeWrite(final CompilerSettings settings, final Variables variables) { @@ -231,7 +231,7 @@ public final class EChain extends AExpression { expression = expression.cast(settings, variables); this.statement = true; - this.actual = read ? last.after : Definition.voidType; + this.actual = read ? last.after : Definition.VOID_TYPE; } private void analyzeRead() { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java index 68c45f4870e..75dd1bb1f14 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java @@ -119,7 +119,7 @@ public final class EComp extends AExpression { } } - actual = Definition.booleanType; + actual = Definition.BOOLEAN_TYPE; } private void analyzeEqR(final CompilerSettings settings, final Variables variables) { @@ -161,7 +161,7 @@ public final class EComp extends AExpression { } } - actual = Definition.booleanType; + actual = Definition.BOOLEAN_TYPE; } private void analyzeNE(final CompilerSettings settings, final Variables variables) { @@ -207,7 +207,7 @@ public final class EComp extends AExpression { } } - actual = Definition.booleanType; + actual = Definition.BOOLEAN_TYPE; } private void analyzeNER(final CompilerSettings settings, final Variables variables) { @@ -249,7 +249,7 @@ public final class EComp extends AExpression { } } - actual = Definition.booleanType; + actual = Definition.BOOLEAN_TYPE; } private void analyzeGTE(final CompilerSettings settings, final Variables variables) { @@ -285,7 +285,7 @@ public final class EComp extends AExpression { } } - actual = Definition.booleanType; + actual = Definition.BOOLEAN_TYPE; } private void analyzeGT(final CompilerSettings settings, final Variables variables) { @@ -321,7 +321,7 @@ public final class EComp extends AExpression { } } - actual = Definition.booleanType; + actual = Definition.BOOLEAN_TYPE; } private void analyzeLTE(final CompilerSettings settings, final Variables variables) { @@ -357,7 +357,7 @@ public final class EComp extends AExpression { } } - actual = Definition.booleanType; + actual = Definition.BOOLEAN_TYPE; } private void analyzeLT(final CompilerSettings settings, final Variables variables) { @@ -393,7 +393,7 @@ public final class EComp extends AExpression { } } - actual = Definition.booleanType; + actual = Definition.BOOLEAN_TYPE; } @Override @@ -456,7 +456,7 @@ public final class EComp extends AExpression { if (right.isNull) { adapter.ifNull(jump); } else if (!left.isNull && operation == Operation.EQ) { - adapter.invokeStatic(Definition.defobjType.type, DEF_EQ_CALL); + adapter.invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_EQ_CALL); } else { adapter.ifCmp(rtype, MethodWriter.EQ, jump); } @@ -464,19 +464,19 @@ public final class EComp extends AExpression { if (right.isNull) { adapter.ifNonNull(jump); } else if (!left.isNull && operation == Operation.NE) { - adapter.invokeStatic(Definition.defobjType.type, DEF_EQ_CALL); + adapter.invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_EQ_CALL); adapter.ifZCmp(MethodWriter.EQ, jump); } else { adapter.ifCmp(rtype, MethodWriter.NE, jump); } } else if (lt) { - adapter.invokeStatic(Definition.defobjType.type, DEF_LT_CALL); + adapter.invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_LT_CALL); } else if (lte) { - adapter.invokeStatic(Definition.defobjType.type, DEF_LTE_CALL); + adapter.invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_LTE_CALL); } else if (gt) { - adapter.invokeStatic(Definition.defobjType.type, DEF_GT_CALL); + adapter.invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_GT_CALL); } else if (gte) { - adapter.invokeStatic(Definition.defobjType.type, DEF_GTE_CALL); + adapter.invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_GTE_CALL); } else { throw new IllegalStateException(error("Illegal tree structure.")); } @@ -493,7 +493,7 @@ public final class EComp extends AExpression { if (right.isNull) { adapter.ifNull(jump); } else if (operation == Operation.EQ) { - adapter.invokeStatic(Definition.utilityType.type, CHECKEQUALS); + adapter.invokeStatic(Definition.UTILITY_TYPE.type, CHECKEQUALS); if (branch) { adapter.ifZCmp(MethodWriter.NE, jump); @@ -507,7 +507,7 @@ public final class EComp extends AExpression { if (right.isNull) { adapter.ifNonNull(jump); } else if (operation == Operation.NE) { - adapter.invokeStatic(Definition.utilityType.type, CHECKEQUALS); + adapter.invokeStatic(Definition.UTILITY_TYPE.type, CHECKEQUALS); adapter.ifZCmp(MethodWriter.EQ, jump); } else { adapter.ifCmp(rtype, MethodWriter.NE, jump); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java index e084974fb33..c20391a9d41 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java @@ -47,7 +47,7 @@ public final class EConditional extends AExpression { @Override void analyze(final CompilerSettings settings, final Variables variables) { - condition.expected = Definition.booleanType; + condition.expected = Definition.BOOLEAN_TYPE; condition.analyze(settings, variables); condition = condition.cast(settings, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java index e590ee41852..6ee486c9470 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java @@ -40,23 +40,23 @@ final class EConstant extends AExpression { @Override void analyze(final CompilerSettings settings, final Variables variables) { if (constant instanceof String) { - actual = Definition.stringType; + actual = Definition.STRING_TYPE; } else if (constant instanceof Double) { - actual = Definition.doubleType; + actual = Definition.DOUBLE_TYPE; } else if (constant instanceof Float) { - actual = Definition.floatType; + actual = Definition.FLOAT_TYPE; } else if (constant instanceof Long) { - actual = Definition.longType; + actual = Definition.LONG_TYPE; } else if (constant instanceof Integer) { - actual = Definition.intType; + actual = Definition.INT_TYPE; } else if (constant instanceof Character) { - actual = Definition.charType; + actual = Definition.CHAR_TYPE; } else if (constant instanceof Short) { - actual = Definition.shortType; + actual = Definition.SHORT_TYPE; } else if (constant instanceof Byte) { - actual = Definition.byteType; + actual = Definition.BYTE_TYPE; } else if (constant instanceof Boolean) { - actual = Definition.booleanType; + actual = Definition.BOOLEAN_TYPE; } else { throw new IllegalStateException(error("Illegal tree structure.")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java index 3f1d3a3fc26..7c942dff32c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java @@ -42,14 +42,14 @@ 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.floatType; + actual = Definition.FLOAT_TYPE; } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid float constant [" + value + "].")); } } else { try { constant = Double.parseDouble(value); - actual = Definition.doubleType; + actual = Definition.DOUBLE_TYPE; } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid double constant [" + value + "].")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java index 3fcabccff17..c7c93951223 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java @@ -45,7 +45,7 @@ public final class ENull extends AExpression { actual = expected; } else { - actual = Definition.objectType; + actual = Definition.OBJECT_TYPE; } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java index e68de5b4128..75f85703bc8 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java @@ -49,7 +49,7 @@ public final class ENumeric extends AExpression { try { constant = Double.parseDouble(value.substring(0, value.length() - 1)); - actual = Definition.doubleType; + actual = Definition.DOUBLE_TYPE; } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid double constant [" + value + "].")); } @@ -60,14 +60,14 @@ public final class ENumeric extends AExpression { try { constant = Float.parseFloat(value.substring(0, value.length() - 1)); - actual = Definition.floatType; + actual = Definition.FLOAT_TYPE; } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("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.longType; + actual = Definition.LONG_TYPE; } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid long constant [" + value + "].")); } @@ -78,16 +78,16 @@ public final class ENumeric extends AExpression { if (sort == Sort.BYTE && integer >= Byte.MIN_VALUE && integer <= Byte.MAX_VALUE) { constant = (byte)integer; - actual = Definition.byteType; + actual = Definition.BYTE_TYPE; } else if (sort == Sort.CHAR && integer >= Character.MIN_VALUE && integer <= Character.MAX_VALUE) { constant = (char)integer; - actual = Definition.charType; + actual = Definition.CHAR_TYPE; } else if (sort == Sort.SHORT && integer >= Short.MIN_VALUE && integer <= Short.MAX_VALUE) { constant = (short)integer; - actual = Definition.shortType; + actual = Definition.SHORT_TYPE; } else { constant = integer; - actual = Definition.intType; + actual = Definition.INT_TYPE; } } catch (final NumberFormatException exception) { throw new IllegalArgumentException(error("Invalid int constant [" + value + "].")); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java index 8ab97dcbde6..115db1499f4 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java @@ -63,7 +63,7 @@ public final class EUnary extends AExpression { } void analyzeNot(final CompilerSettings settings, final Variables variables) { - child.expected = Definition.booleanType; + child.expected = Definition.BOOLEAN_TYPE; child.analyze(settings, variables); child = child.cast(settings, variables); @@ -71,7 +71,7 @@ public final class EUnary extends AExpression { constant = !(boolean)child.constant; } - actual = Definition.booleanType; + actual = Definition.BOOLEAN_TYPE; } void analyzeBWNot(final CompilerSettings settings, final Variables variables) { @@ -191,7 +191,7 @@ public final class EUnary extends AExpression { if (operation == Operation.BWNOT) { if (sort == Sort.DEF) { - adapter.invokeStatic(Definition.defobjType.type, DEF_NOT_CALL); + adapter.invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_NOT_CALL); } else { if (sort == Sort.INT) { adapter.push(-1); @@ -205,7 +205,7 @@ public final class EUnary extends AExpression { } } else if (operation == Operation.SUB) { if (sort == Sort.DEF) { - adapter.invokeStatic(Definition.defobjType.type, DEF_NEG_CALL); + adapter.invokeStatic(Definition.DEF_UTIL_TYPE.type, DEF_NEG_CALL); } else { adapter.math(MethodWriter.NEG, type); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java index c4026bb529e..4678e9766f3 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java @@ -46,7 +46,7 @@ public final class LArrayLength extends ALink { throw new IllegalArgumentException(error("Cannot write to read-only array field [length].")); } - after = Definition.intType; + after = Definition.INT_TYPE; } else { throw new IllegalArgumentException(error("Illegal field access [" + value + "].")); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java index 2a8da6e1892..1a1d4b5927e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java @@ -50,7 +50,7 @@ public final class LBrace extends ALink { final Sort sort = before.sort; if (sort == Sort.ARRAY) { - index.expected = Definition.intType; + index.expected = Definition.INT_TYPE; index.analyze(settings, variables); index = index.cast(settings, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java index 842cc7c41bb..e07dd9ab6ff 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java @@ -47,7 +47,7 @@ final class LDefArray extends ALink implements IDefLink { index.expected = index.actual; index = index.cast(settings, variables); - after = Definition.defType; + after = Definition.DEF_TYPE; return this; } @@ -59,13 +59,13 @@ final class LDefArray extends ALink implements IDefLink { @Override void load(final CompilerSettings settings, final MethodWriter adapter) { - final String desc = Type.getMethodDescriptor(after.type, Definition.defType.type, index.actual.type); + final String desc = Type.getMethodDescriptor(after.type, Definition.DEF_TYPE.type, index.actual.type); adapter.invokeDynamic("arrayLoad", desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.ARRAY_LOAD); } @Override void store(final CompilerSettings settings, final MethodWriter adapter) { - final String desc = Type.getMethodDescriptor(Definition.voidType.type, Definition.defType.type, + final String desc = Type.getMethodDescriptor(Definition.VOID_TYPE.type, Definition.DEF_TYPE.type, index.actual.type, after.type); adapter.invokeDynamic("arrayStore", desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.ARRAY_STORE); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java index e3b7c6c583d..f15f132cbec 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java @@ -55,7 +55,7 @@ final class LDefCall extends ALink implements IDefLink { } statement = true; - after = Definition.defType; + after = Definition.DEF_TYPE; return this; } @@ -71,7 +71,7 @@ final class LDefCall extends ALink implements IDefLink { signature.append('('); // first parameter is the receiver, we never know its type: always Object - signature.append(Definition.defType.type.getDescriptor()); + signature.append(Definition.DEF_TYPE.type.getDescriptor()); // TODO: remove our explicit conversions and feed more type information for return value, // it can avoid some unnecessary boxing etc. diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java index f54bf316254..84850826e6f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java @@ -44,7 +44,7 @@ final class LDefField extends ALink implements IDefLink { @Override ALink analyze(final CompilerSettings settings, final Variables variables) { - after = Definition.defType; + after = Definition.DEF_TYPE; return this; } @@ -56,13 +56,13 @@ final class LDefField extends ALink implements IDefLink { @Override void load(final CompilerSettings settings, final MethodWriter adapter) { - final String desc = Type.getMethodDescriptor(after.type, Definition.defType.type); + final String desc = Type.getMethodDescriptor(after.type, Definition.DEF_TYPE.type); adapter.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.LOAD); } @Override void store(final CompilerSettings settings, final MethodWriter adapter) { - final String desc = Type.getMethodDescriptor(Definition.voidType.type, Definition.defType.type, after.type); + final String desc = Type.getMethodDescriptor(Definition.VOID_TYPE.type, Definition.DEF_TYPE.type, after.type); adapter.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.STORE); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java index 1ee0f8fa3ed..9541459a615 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java @@ -61,7 +61,7 @@ final class LListShortcut extends ALink { } if ((load || store) && (!load || getter != null) && (!store || setter != null)) { - index.expected = Definition.intType; + index.expected = Definition.INT_TYPE; index.analyze(settings, variables); index = index.cast(settings, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java index 9d3e5d307fe..2faad220db6 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java @@ -63,7 +63,7 @@ public final class LNewArray extends ALink { for (int argument = 0; argument < arguments.size(); ++argument) { final AExpression expression = arguments.get(argument); - expression.expected = Definition.intType; + expression.expected = Definition.INT_TYPE; expression.analyze(settings, variables); arguments.set(argument, expression.cast(settings, variables)); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java index 5fe7c22a457..115c4c57ab3 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java @@ -45,7 +45,7 @@ public final class LString extends ALink { throw new IllegalArgumentException(error("Must read String constant [" + string + "].")); } - after = Definition.stringType; + after = Definition.STRING_TYPE; return this; } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java index ade9f9ba221..249ff75c744 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java @@ -53,7 +53,7 @@ public final class SDo extends AStatement { throw new IllegalArgumentException(error("Extraneous do while loop.")); } - condition.expected = Definition.booleanType; + condition.expected = Definition.BOOLEAN_TYPE; condition.analyze(settings, variables); condition = condition.cast(settings, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java index 1f107548dff..aaf63a3c923 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java @@ -49,7 +49,7 @@ public final class SExpression extends AStatement { final boolean rtn = lastSource && expression.actual.sort != Sort.VOID; - expression.expected = rtn ? Definition.objectType : expression.actual; + expression.expected = rtn ? Definition.OBJECT_TYPE : expression.actual; expression = expression.cast(settings, variables); methodEscape = rtn; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java index ae59382039d..cbce549f1cb 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java @@ -70,7 +70,7 @@ public final class SFor extends AStatement { if (condition != null) { - condition.expected = Definition.booleanType; + condition.expected = Definition.BOOLEAN_TYPE; condition.analyze(settings, variables); condition = condition.cast(settings, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java index 40c20a1cb87..1fadc4f0ac4 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java @@ -45,7 +45,7 @@ public final class SIfElse extends AStatement { @Override void analyze(final CompilerSettings settings, final Variables variables) { - condition.expected = Definition.booleanType; + condition.expected = Definition.BOOLEAN_TYPE; condition.analyze(settings, variables); condition = condition.cast(settings, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java index 4caf57f463b..f2c051ac1f6 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java @@ -39,7 +39,7 @@ public final class SReturn extends AStatement { @Override void analyze(final CompilerSettings settings, final Variables variables) { - expression.expected = Definition.objectType; + expression.expected = Definition.OBJECT_TYPE; expression.analyze(settings, variables); expression = expression.cast(settings, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java index 8a2909d0a3b..f9a719a5f77 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java @@ -39,7 +39,7 @@ public final class SThrow extends AStatement { @Override void analyze(final CompilerSettings settings, final Variables variables) { - expression.expected = Definition.exceptionType; + expression.expected = Definition.EXCEPTION_TYPE; expression.analyze(settings, variables); expression = expression.cast(settings, variables); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java index a6d88fdcced..98616d11499 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java @@ -44,7 +44,7 @@ public final class SWhile extends AStatement { void analyze(final CompilerSettings settings, final Variables variables) { variables.incrementScope(); - condition.expected = Definition.booleanType; + condition.expected = Definition.BOOLEAN_TYPE; condition.analyze(settings, variables); condition = condition.cast(settings, variables); From ce9b36590aa884c9bcabe183a974175d41901314 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Fri, 20 May 2016 09:36:09 -0400 Subject: [PATCH 18/22] simplify tree node use of compiler settings --- .../org/elasticsearch/painless/Analyzer.java | 2 +- .../org/elasticsearch/painless/Compiler.java | 2 +- .../org/elasticsearch/painless/Writer.java | 2 +- .../elasticsearch/painless/antlr/Walker.java | 15 +- .../painless/node/AExpression.java | 13 +- .../elasticsearch/painless/node/ALink.java | 13 +- .../painless/node/AStatement.java | 7 +- .../elasticsearch/painless/node/EBinary.java | 147 +++++++++--------- .../elasticsearch/painless/node/EBool.java | 31 ++-- .../elasticsearch/painless/node/EBoolean.java | 7 +- .../elasticsearch/painless/node/ECast.java | 9 +- .../elasticsearch/painless/node/EChain.java | 53 ++++--- .../elasticsearch/painless/node/EComp.java | 107 +++++++------ .../painless/node/EConditional.java | 26 ++-- .../painless/node/EConstant.java | 7 +- .../elasticsearch/painless/node/EDecimal.java | 7 +- .../painless/node/EExplicit.java | 15 +- .../elasticsearch/painless/node/ENull.java | 7 +- .../elasticsearch/painless/node/ENumeric.java | 7 +- .../elasticsearch/painless/node/EUnary.java | 45 +++--- .../painless/node/LArrayLength.java | 11 +- .../elasticsearch/painless/node/LBrace.java | 23 ++- .../elasticsearch/painless/node/LCall.java | 19 ++- .../elasticsearch/painless/node/LCast.java | 11 +- .../painless/node/LDefArray.java | 17 +- .../elasticsearch/painless/node/LDefCall.java | 17 +- .../painless/node/LDefField.java | 11 +- .../elasticsearch/painless/node/LField.java | 23 ++- .../painless/node/LListShortcut.java | 17 +- .../painless/node/LMapShortcut.java | 17 +- .../painless/node/LNewArray.java | 17 +- .../elasticsearch/painless/node/LNewObj.java | 19 ++- .../painless/node/LShortcut.java | 11 +- .../elasticsearch/painless/node/LString.java | 11 +- .../painless/node/LVariable.java | 11 +- .../elasticsearch/painless/node/SBlock.java | 15 +- .../elasticsearch/painless/node/SBreak.java | 7 +- .../painless/node/SContinue.java | 7 +- .../painless/node/SDeclBlock.java | 11 +- .../painless/node/SDeclaration.java | 13 +- .../org/elasticsearch/painless/node/SDo.java | 21 +-- .../painless/node/SExpression.java | 13 +- .../org/elasticsearch/painless/node/SFor.java | 35 +++-- .../elasticsearch/painless/node/SIfElse.java | 22 ++- .../elasticsearch/painless/node/SReturn.java | 13 +- .../elasticsearch/painless/node/SSource.java | 11 +- .../elasticsearch/painless/node/SThrow.java | 13 +- .../elasticsearch/painless/node/STrap.java | 11 +- .../org/elasticsearch/painless/node/STry.java | 15 +- .../elasticsearch/painless/node/SWhile.java | 21 +-- 50 files changed, 473 insertions(+), 512 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Analyzer.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Analyzer.java index 2cd62b4c3d4..e81e828c875 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Analyzer.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Analyzer.java @@ -29,7 +29,7 @@ final class Analyzer { static Variables analyze(final CompilerSettings settings, final Reserved shortcut, final SSource root) { final Variables variables = new Variables(settings, shortcut); - root.analyze(settings, variables); + root.analyze(variables); return variables; } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Compiler.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Compiler.java index 65d7c78555c..16ad355177f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Compiler.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Compiler.java @@ -112,7 +112,7 @@ final class Compiler { } final Reserved reserved = new Reserved(); - final SSource root = Walker.buildPainlessTree(source, reserved); + final SSource root = Walker.buildPainlessTree(source, reserved, settings); final Variables variables = Analyzer.analyze(settings, reserved, root); return Writer.write(settings, name, source, variables, root); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Writer.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Writer.java index 977a591b7af..57103d53764 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Writer.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Writer.java @@ -175,7 +175,7 @@ final class Writer { adapter.visitVarInsn(Opcodes.ISTORE, loop.slot); } - root.write(settings, adapter); + root.write(adapter); adapter.endMethod(); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java index 4f6e2f5e87c..9ecf6754248 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/antlr/Walker.java @@ -22,6 +22,7 @@ package org.elasticsearch.painless.antlr; import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.ParserRuleContext; +import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Operation; import org.elasticsearch.painless.Variables.Reserved; import org.elasticsearch.painless.antlr.PainlessParser.AfterthoughtContext; @@ -121,15 +122,17 @@ import java.util.List; */ public final class Walker extends PainlessParserBaseVisitor { - public static SSource buildPainlessTree(final String source, final Reserved reserved) { - return new Walker(source, reserved).source; + public static SSource buildPainlessTree(String source, Reserved reserved, CompilerSettings settings) { + return new Walker(source, reserved, settings).source; } private final Reserved reserved; private final SSource source; + private final CompilerSettings settings; - private Walker(final String source, final Reserved reserved) { + private Walker(String source, Reserved reserved, CompilerSettings settings) { this.reserved = reserved; + this.settings = settings; this.source = (SSource)visit(buildAntlrTree(source)); } @@ -181,7 +184,7 @@ public final class Walker extends PainlessParserBaseVisitor { reserved.usesLoop(); - return new SWhile(line(ctx), location(ctx), condition, block); + return new SWhile(line(ctx), location(ctx), condition, block, settings.getMaxLoopCounter()); } @Override @@ -191,7 +194,7 @@ public final class Walker extends PainlessParserBaseVisitor { reserved.usesLoop(); - return new SDo(line(ctx), location(ctx), block, condition); + return new SDo(line(ctx), location(ctx), block, condition, settings.getMaxLoopCounter()); } @Override @@ -203,7 +206,7 @@ public final class Walker extends PainlessParserBaseVisitor { reserved.usesLoop(); - return new SFor(line(ctx), location(ctx), intializer, condition, afterthought, block); + return new SFor(line(ctx), location(ctx), intializer, condition, afterthought, block, settings.getMaxLoopCounter()); } @Override diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java index f741d62921f..110b5a54189 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AExpression.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition.Cast; import org.elasticsearch.painless.Definition.Type; import org.elasticsearch.painless.AnalyzerCaster; @@ -100,19 +99,19 @@ public abstract class AExpression extends ANode { /** * Checks for errors and collects data for the writing phase. */ - abstract void analyze(final CompilerSettings settings, final Variables variables); + abstract void analyze(Variables variables); /** * Writes ASM based on the data collected during the analysis phase. */ - abstract void write(final CompilerSettings settings, final MethodWriter adapter); + abstract void write(MethodWriter adapter); /** * Inserts {@link ECast} nodes into the tree for implicit casts. Also replaces * nodes with the constant variable set to a non-null value with {@link EConstant}. * @return The new child node for the parent node calling this method. */ - AExpression cast(final CompilerSettings settings, final Variables variables) { + AExpression cast(Variables variables) { final Cast cast = AnalyzerCaster.getLegalCast(location, actual, expected, explicit); if (cast == null) { @@ -120,7 +119,7 @@ public abstract class AExpression extends ANode { return this; } else { final EConstant econstant = new EConstant(line, location, constant); - econstant.analyze(settings, variables); + econstant.analyze(variables); if (!expected.equals(econstant.actual)) { throw new IllegalStateException(error("Illegal tree structure.")); @@ -141,7 +140,7 @@ public abstract class AExpression extends ANode { constant = AnalyzerCaster.constCast(location, constant, cast); final EConstant econstant = new EConstant(line, location, constant); - econstant.analyze(settings, variables); + econstant.analyze(variables); if (!expected.equals(econstant.actual)) { throw new IllegalStateException(error("Illegal tree structure.")); @@ -155,7 +154,7 @@ public abstract class AExpression extends ANode { return ecast; } else { final EConstant econstant = new EConstant(line, location, constant); - econstant.analyze(settings, variables); + econstant.analyze(variables); if (!actual.equals(econstant.actual)) { throw new IllegalStateException(error("Illegal tree structure.")); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ALink.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ALink.java index 8f8e226006e..e134e7fbcb9 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ALink.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ALink.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition.Type; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -74,7 +73,7 @@ public abstract class ALink extends ANode { */ String string = null; - ALink(final int line, final String location, final int size) { + ALink(int line, String location, int size) { super(line, location); this.size = size; @@ -86,27 +85,27 @@ public abstract class ALink extends ANode { * def or a shortcut is used. Otherwise, returns itself. This will be * updated into the {@link EChain} node's list of links. */ - abstract ALink analyze(final CompilerSettings settings, final Variables variables); + abstract ALink analyze(Variables variables); /** * Write values before a load/store occurs such as an array index. */ - abstract void write(final CompilerSettings settings, final MethodWriter adapter); + abstract void write(MethodWriter adapter); /** * Write a load for the specific link type. */ - abstract void load(final CompilerSettings settings, final MethodWriter adapter); + abstract void load(MethodWriter adapter); /** * Write a store for the specific link type. */ - abstract void store(final CompilerSettings settings, final MethodWriter adapter); + abstract void store(MethodWriter adapter); /** * Used to copy link data from one to another during analysis in the case of replacement. */ - final ALink copy(final ALink link) { + final ALink copy(ALink link) { load = link.load; store = link.store; statik = link.statik; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AStatement.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AStatement.java index f80d5e7b4fd..ebc4a166268 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AStatement.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/AStatement.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Variables; import org.objectweb.asm.Label; import org.elasticsearch.painless.MethodWriter; @@ -108,17 +107,17 @@ public abstract class AStatement extends ANode { */ Label brake = null; - AStatement(final int line, final String location) { + AStatement(int line, String location) { super(line, location); } /** * Checks for errors and collects data for the writing phase. */ - abstract void analyze(final CompilerSettings settings, final Variables variables); + abstract void analyze(Variables variables); /** * Writes ASM based on the data collected during the analysis phase. */ - abstract void write(final CompilerSettings settings, final MethodWriter adapter); + abstract void write(MethodWriter adapter); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java index 0046d498074..b94ef09c042 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBinary.java @@ -20,7 +20,6 @@ package org.elasticsearch.painless.node; import org.elasticsearch.painless.AnalyzerCaster; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Sort; import org.elasticsearch.painless.Definition.Type; @@ -39,7 +38,7 @@ public final class EBinary extends AExpression { boolean cat = false; - public EBinary(final int line, final String location, final Operation operation, final AExpression left, final AExpression right) { + public EBinary(int line, String location, Operation operation, AExpression left, AExpression right) { super(line, location); this.operation = operation; @@ -48,37 +47,37 @@ public final class EBinary extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { if (operation == Operation.MUL) { - analyzeMul(settings, variables); + analyzeMul(variables); } else if (operation == Operation.DIV) { - analyzeDiv(settings, variables); + analyzeDiv(variables); } else if (operation == Operation.REM) { - analyzeRem(settings, variables); + analyzeRem(variables); } else if (operation == Operation.ADD) { - analyzeAdd(settings, variables); + analyzeAdd(variables); } else if (operation == Operation.SUB) { - analyzeSub(settings, variables); + analyzeSub(variables); } else if (operation == Operation.LSH) { - analyzeLSH(settings, variables); + analyzeLSH(variables); } else if (operation == Operation.RSH) { - analyzeRSH(settings, variables); + analyzeRSH(variables); } else if (operation == Operation.USH) { - analyzeUSH(settings, variables); + analyzeUSH(variables); } else if (operation == Operation.BWAND) { - analyzeBWAnd(settings, variables); + analyzeBWAnd(variables); } else if (operation == Operation.XOR) { - analyzeXor(settings, variables); + analyzeXor(variables); } else if (operation == Operation.BWOR) { - analyzeBWOr(settings, variables); + analyzeBWOr(variables); } else { throw new IllegalStateException(error("Illegal tree structure.")); } } - private void analyzeMul(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeMul(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); @@ -90,8 +89,8 @@ public final class EBinary extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -112,9 +111,9 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeDiv(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeDiv(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); @@ -126,8 +125,8 @@ public final class EBinary extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -148,9 +147,9 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeRem(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeRem(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); @@ -162,8 +161,8 @@ public final class EBinary extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -184,9 +183,9 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeAdd(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeAdd(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteAdd(left.actual, right.actual); @@ -214,8 +213,8 @@ public final class EBinary extends AExpression { right.expected = promote; } - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { if (sort == Sort.INT) { @@ -236,9 +235,9 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeSub(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeSub(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); @@ -250,8 +249,8 @@ public final class EBinary extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -272,9 +271,9 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeLSH(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeLSH(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(left.actual, false, true); @@ -287,8 +286,8 @@ public final class EBinary extends AExpression { right.expected = Definition.INT_TYPE; right.explicit = true; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -305,9 +304,9 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeRSH(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeRSH(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(left.actual, false, true); @@ -320,8 +319,8 @@ public final class EBinary extends AExpression { right.expected = Definition.INT_TYPE; right.explicit = true; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -338,9 +337,9 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeUSH(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeUSH(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(left.actual, false, true); @@ -353,8 +352,8 @@ public final class EBinary extends AExpression { right.expected = Definition.INT_TYPE; right.explicit = true; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -371,9 +370,9 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeBWAnd(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeBWAnd(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, false, true); @@ -385,8 +384,8 @@ public final class EBinary extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -403,9 +402,9 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeXor(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeXor(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteXor(left.actual, right.actual); @@ -417,8 +416,8 @@ public final class EBinary extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -437,9 +436,9 @@ public final class EBinary extends AExpression { actual = promote; } - private void analyzeBWOr(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeBWOr(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, false, true); @@ -451,8 +450,8 @@ public final class EBinary extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -470,19 +469,19 @@ public final class EBinary extends AExpression { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { if (actual.sort == Sort.STRING && operation == Operation.ADD) { if (!cat) { adapter.writeNewStrings(); } - left.write(settings, adapter); + left.write(adapter); if (!(left instanceof EBinary) || ((EBinary)left).operation != Operation.ADD || left.actual.sort != Sort.STRING) { adapter.writeAppendStrings(left.actual); } - right.write(settings, adapter); + right.write(adapter); if (!(right instanceof EBinary) || ((EBinary)right).operation != Operation.ADD || right.actual.sort != Sort.STRING) { adapter.writeAppendStrings(right.actual); @@ -492,8 +491,8 @@ public final class EBinary extends AExpression { adapter.writeToStrings(); } } else { - left.write(settings, adapter); - right.write(settings, adapter); + left.write(adapter); + right.write(adapter); adapter.writeBinaryInstruction(location, actual, operation); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java index 1e2af41c0c0..27cd3018ded 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBool.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Operation; import org.elasticsearch.painless.Variables; @@ -35,7 +34,7 @@ public final class EBool extends AExpression { AExpression left; AExpression right; - public EBool(final int line, final String location, final Operation operation, final AExpression left, final AExpression right) { + public EBool(int line, String location, Operation operation, AExpression left, AExpression right) { super(line, location); this.operation = operation; @@ -44,14 +43,14 @@ public final class EBool extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { left.expected = Definition.BOOLEAN_TYPE; - left.analyze(settings, variables); - left = left.cast(settings, variables); + left.analyze(variables); + left = left.cast(variables); right.expected = Definition.BOOLEAN_TYPE; - right.analyze(settings, variables); - right = right.cast(settings, variables); + right.analyze(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { if (operation == Operation.AND) { @@ -67,7 +66,7 @@ public final class EBool extends AExpression { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { if (tru != null || fals != null) { if (operation == Operation.AND) { final Label localfals = fals == null ? new Label() : fals; @@ -76,8 +75,8 @@ public final class EBool extends AExpression { right.tru = tru; right.fals = fals; - left.write(settings, adapter); - right.write(settings, adapter); + left.write(adapter); + right.write(adapter); if (fals == null) { adapter.mark(localfals); @@ -89,8 +88,8 @@ public final class EBool extends AExpression { right.tru = tru; right.fals = fals; - left.write(settings, adapter); - right.write(settings, adapter); + left.write(adapter); + right.write(adapter); if (tru == null) { adapter.mark(localtru); @@ -106,8 +105,8 @@ public final class EBool extends AExpression { left.fals = localfals; right.fals = localfals; - left.write(settings, adapter); - right.write(settings, adapter); + left.write(adapter); + right.write(adapter); adapter.push(true); adapter.goTo(end); @@ -122,8 +121,8 @@ public final class EBool extends AExpression { left.tru = localtru; right.fals = localfals; - left.write(settings, adapter); - right.write(settings, adapter); + left.write(adapter); + right.write(adapter); adapter.mark(localtru); adapter.push(true); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java index 2e019c576e0..27d7bb9a626 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EBoolean.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -29,19 +28,19 @@ import org.elasticsearch.painless.MethodWriter; */ public final class EBoolean extends AExpression { - public EBoolean(final int line, final String location, final boolean constant) { + public EBoolean(int line, String location, boolean constant) { super(line, location); this.constant = constant; } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { actual = Definition.BOOLEAN_TYPE; } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { throw new IllegalArgumentException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECast.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECast.java index c46957f78d9..7a8c4a29b60 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECast.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECast.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition.Cast; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -35,7 +34,7 @@ final class ECast extends AExpression { Cast cast = null; - ECast(final int line, final String location, final AExpression child, final Cast cast) { + ECast(int line, String location, AExpression child, Cast cast) { super(line, location); this.type = null; @@ -45,13 +44,13 @@ final class ECast extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { throw new IllegalStateException(error("Illegal tree structure.")); } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { - child.write(settings, adapter); + void write(MethodWriter adapter) { + child.write(adapter); adapter.writeCast(cast); adapter.writeBranch(tru, fals); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java index 2f8ad66f101..8f2d3812943 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EChain.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Cast; import org.elasticsearch.painless.Definition.Sort; @@ -47,8 +46,8 @@ public final class EChain extends AExpression { Cast there = null; Cast back = null; - public EChain(final int line, final String location, final List links, - final boolean pre, final boolean post, final Operation operation, final AExpression expression) { + public EChain(int line, String location, List links, + boolean pre, boolean post, Operation operation, AExpression expression) { super(line, location); this.links = links; @@ -59,20 +58,20 @@ public final class EChain extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Variables variables) { - analyzeLinks(settings, variables); + void analyze(Variables variables) { + analyzeLinks(variables); analyzeIncrDecr(); if (operation != null) { - analyzeCompound(settings, variables); + analyzeCompound(variables); } else if (expression != null) { - analyzeWrite(settings, variables); + analyzeWrite(variables); } else { analyzeRead(); } } - private void analyzeLinks(final CompilerSettings settings, final Variables variables) { + private void analyzeLinks(Variables variables) { ALink previous = null; int index = 0; @@ -92,7 +91,7 @@ public final class EChain extends AExpression { current.store = expression != null || pre || post; } - final ALink analyzed = current.analyze(settings, variables); + final ALink analyzed = current.analyze(variables); if (analyzed == null) { links.remove(index); @@ -153,10 +152,10 @@ public final class EChain extends AExpression { } } - private void analyzeCompound(final CompilerSettings settings, final Variables variables) { + private void analyzeCompound(Variables variables) { final ALink last = links.get(links.size() - 1); - expression.analyze(settings, variables); + expression.analyze(variables); if (operation == Operation.MUL) { promote = AnalyzerCaster.promoteNumeric(last.after, expression.actual, true, true); @@ -205,7 +204,7 @@ public final class EChain extends AExpression { expression.expected = promote; } - expression = expression.cast(settings, variables); + expression = expression.cast(variables); there = AnalyzerCaster.getLegalCast(location, last.after, promote, false); back = AnalyzerCaster.getLegalCast(location, promote, last.after, true); @@ -214,21 +213,21 @@ public final class EChain extends AExpression { this.actual = read ? last.after : Definition.VOID_TYPE; } - private void analyzeWrite(final CompilerSettings settings, final Variables variables) { + private void analyzeWrite(Variables variables) { final ALink last = links.get(links.size() - 1); // If the store node is a DEF node, we remove the cast to DEF from the expression // and promote the real type to it: if (last instanceof IDefLink) { - expression.analyze(settings, variables); + expression.analyze(variables); last.after = expression.expected = expression.actual; } else { // otherwise we adapt the type of the expression to the store type expression.expected = last.after; - expression.analyze(settings, variables); + expression.analyze(variables); } - expression = expression.cast(settings, variables); + expression = expression.cast(variables); this.statement = true; this.actual = read ? last.after : Definition.VOID_TYPE; @@ -248,7 +247,7 @@ public final class EChain extends AExpression { } @Override - void write(final CompilerSettings settings,final MethodWriter adapter) { + void write(MethodWriter adapter) { if (cat) { adapter.writeNewStrings(); } @@ -256,15 +255,15 @@ public final class EChain extends AExpression { final ALink last = links.get(links.size() - 1); for (final ALink link : links) { - link.write(settings, adapter); + link.write(adapter); if (link == last && link.store) { if (cat) { adapter.writeDup(link.size, 1); - link.load(settings, adapter); + link.load(adapter); adapter.writeAppendStrings(link.after); - expression.write(settings, adapter); + expression.write(adapter); if (!(expression instanceof EBinary) || ((EBinary)expression).operation != Operation.ADD || expression.actual.sort != Sort.STRING) { @@ -278,17 +277,17 @@ public final class EChain extends AExpression { adapter.writeDup(link.after.sort.size, link.size); } - link.store(settings, adapter); + link.store(adapter); } else if (operation != null) { adapter.writeDup(link.size, 0); - link.load(settings, adapter); + link.load(adapter); if (link.load && post) { adapter.writeDup(link.after.sort.size, link.size); } adapter.writeCast(there); - expression.write(settings, adapter); + expression.write(adapter); adapter.writeBinaryInstruction(location, promote, operation); adapter.writeCast(back); @@ -297,18 +296,18 @@ public final class EChain extends AExpression { adapter.writeDup(link.after.sort.size, link.size); } - link.store(settings, adapter); + link.store(adapter); } else { - expression.write(settings, adapter); + expression.write(adapter); if (link.load) { adapter.writeDup(link.after.sort.size, link.size); } - link.store(settings, adapter); + link.store(adapter); } } else { - link.load(settings, adapter); + link.load(adapter); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java index 75dd1bb1f14..046ab1bfdf6 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EComp.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Sort; import org.elasticsearch.painless.Definition.Type; @@ -45,7 +44,7 @@ public final class EComp extends AExpression { AExpression left; AExpression right; - public EComp(final int line, final String location, final Operation operation, final AExpression left, final AExpression right) { + public EComp(int line, String location, Operation operation, AExpression left, AExpression right) { super(line, location); this.operation = operation; @@ -54,31 +53,31 @@ public final class EComp extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { if (operation == Operation.EQ) { - analyzeEq(settings, variables); + analyzeEq(variables); } else if (operation == Operation.EQR) { - analyzeEqR(settings, variables); + analyzeEqR(variables); } else if (operation == Operation.NE) { - analyzeNE(settings, variables); + analyzeNE(variables); } else if (operation == Operation.NER) { - analyzeNER(settings, variables); + analyzeNER(variables); } else if (operation == Operation.GTE) { - analyzeGTE(settings, variables); + analyzeGTE(variables); } else if (operation == Operation.GT) { - analyzeGT(settings, variables); + analyzeGT(variables); } else if (operation == Operation.LTE) { - analyzeLTE(settings, variables); + analyzeLTE(variables); } else if (operation == Operation.LT) { - analyzeLT(settings, variables); + analyzeLT(variables); } else { throw new IllegalStateException(error("Illegal tree structure.")); } } - private void analyzeEq(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeEq(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteEquality(left.actual, right.actual); @@ -90,8 +89,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.isNull && right.isNull) { throw new IllegalArgumentException(error("Extraneous comparison of null constants.")); @@ -122,9 +121,9 @@ public final class EComp extends AExpression { actual = Definition.BOOLEAN_TYPE; } - private void analyzeEqR(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeEqR(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteReference(left.actual, right.actual); @@ -136,8 +135,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.isNull && right.isNull) { throw new IllegalArgumentException(error("Extraneous comparison of null constants.")); @@ -164,9 +163,9 @@ public final class EComp extends AExpression { actual = Definition.BOOLEAN_TYPE; } - private void analyzeNE(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeNE(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteEquality(left.actual, right.actual); @@ -178,8 +177,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.isNull && right.isNull) { throw new IllegalArgumentException(error("Extraneous comparison of null constants.")); @@ -210,9 +209,9 @@ public final class EComp extends AExpression { actual = Definition.BOOLEAN_TYPE; } - private void analyzeNER(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeNER(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteReference(left.actual, right.actual); @@ -224,8 +223,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.isNull && right.isNull) { throw new IllegalArgumentException(error("Extraneous comparison of null constants.")); @@ -252,9 +251,9 @@ public final class EComp extends AExpression { actual = Definition.BOOLEAN_TYPE; } - private void analyzeGTE(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeGTE(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); @@ -266,8 +265,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -288,9 +287,9 @@ public final class EComp extends AExpression { actual = Definition.BOOLEAN_TYPE; } - private void analyzeGT(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeGT(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); @@ -302,8 +301,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -324,9 +323,9 @@ public final class EComp extends AExpression { actual = Definition.BOOLEAN_TYPE; } - private void analyzeLTE(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeLTE(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); @@ -338,8 +337,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -360,9 +359,9 @@ public final class EComp extends AExpression { actual = Definition.BOOLEAN_TYPE; } - private void analyzeLT(final CompilerSettings settings, final Variables variables) { - left.analyze(settings, variables); - right.analyze(settings, variables); + private void analyzeLT(Variables variables) { + left.analyze(variables); + right.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(left.actual, right.actual, true, true); @@ -374,8 +373,8 @@ public final class EComp extends AExpression { left.expected = promote; right.expected = promote; - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); if (left.constant != null && right.constant != null) { final Sort sort = promote.sort; @@ -397,15 +396,15 @@ public final class EComp extends AExpression { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { final boolean branch = tru != null || fals != null; final org.objectweb.asm.Type rtype = right.actual.type; final Sort rsort = right.actual.sort; - left.write(settings, adapter); + left.write(adapter); if (!right.isNull) { - right.write(settings, adapter); + right.write(adapter); } final Label jump = tru != null ? tru : fals != null ? fals : new Label(); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java index c20391a9d41..bb2fc4d9d44 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConditional.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Type; import org.elasticsearch.painless.AnalyzerCaster; @@ -36,8 +35,7 @@ public final class EConditional extends AExpression { AExpression left; AExpression right; - public EConditional(final int line, final String location, - final AExpression condition, final AExpression left, final AExpression right) { + public EConditional(int line, String location, AExpression condition, AExpression left, AExpression right) { super(line, location); this.condition = condition; @@ -46,10 +44,10 @@ public final class EConditional extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { condition.expected = Definition.BOOLEAN_TYPE; - condition.analyze(settings, variables); - condition = condition.cast(settings, variables); + condition.analyze(variables); + condition = condition.cast(variables); if (condition.constant != null) { throw new IllegalArgumentException(error("Extraneous conditional statement.")); @@ -61,8 +59,8 @@ public final class EConditional extends AExpression { right.explicit = explicit; actual = expected; - left.analyze(settings, variables); - right.analyze(settings, variables); + left.analyze(variables); + right.analyze(variables); if (expected == null) { final Type promote = AnalyzerCaster.promoteConditional(left.actual, right.actual, left.constant, right.constant); @@ -72,12 +70,12 @@ public final class EConditional extends AExpression { actual = promote; } - left = left.cast(settings, variables); - right = right.cast(settings, variables); + left = left.cast(variables); + right = right.cast(variables); } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { final Label localfals = new Label(); final Label end = new Label(); @@ -85,11 +83,11 @@ public final class EConditional extends AExpression { left.tru = right.tru = tru; left.fals = right.fals = fals; - condition.write(settings, adapter); - left.write(settings, adapter); + condition.write(adapter); + left.write(adapter); adapter.goTo(end); adapter.mark(localfals); - right.write(settings, adapter); + right.write(adapter); adapter.mark(end); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java index 6ee486c9470..ac18b849162 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EConstant.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Sort; import org.elasticsearch.painless.Variables; @@ -31,14 +30,14 @@ import org.elasticsearch.painless.MethodWriter; */ final class EConstant extends AExpression { - EConstant(final int line, final String location, final Object constant) { + EConstant(int line, String location, Object constant) { super(line, location); this.constant = constant; } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { if (constant instanceof String) { actual = Definition.STRING_TYPE; } else if (constant instanceof Double) { @@ -63,7 +62,7 @@ final class EConstant extends AExpression { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { final Sort sort = actual.sort; switch (sort) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java index 7c942dff32c..85e857da3c4 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EDecimal.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -31,14 +30,14 @@ public final class EDecimal extends AExpression { final String value; - public EDecimal(final int line, final String location, final String value) { + public EDecimal(int line, String location, String value) { super(line, location); this.value = value; } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { if (value.endsWith("f") || value.endsWith("F")) { try { constant = Float.parseFloat(value.substring(0, value.length() - 1)); @@ -57,7 +56,7 @@ public final class EDecimal extends AExpression { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { throw new IllegalArgumentException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java index e0afd8f822a..c17d74f14b9 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -32,7 +31,7 @@ public final class EExplicit extends AExpression { final String type; AExpression child; - public EExplicit(final int line, final String location, final String type, final AExpression child) { + public EExplicit(int line, String location, String type, AExpression child) { super(line, location); this.type = type; @@ -40,7 +39,7 @@ public final class EExplicit extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { try { actual = Definition.getType(this.type); } catch (final IllegalArgumentException exception) { @@ -49,19 +48,19 @@ public final class EExplicit extends AExpression { child.expected = actual; child.explicit = true; - child.analyze(settings, variables); - child = child.cast(settings, variables); + child.analyze(variables); + child = child.cast(variables); } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { throw new IllegalArgumentException(error("Illegal tree structure.")); } - AExpression cast(final CompilerSettings settings, final Variables variables) { + AExpression cast(Variables variables) { child.expected = expected; child.explicit = explicit; - return child.cast(settings, variables); + return child.cast(variables); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java index c7c93951223..3a8005b20d6 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENull.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.objectweb.asm.Opcodes; @@ -30,12 +29,12 @@ import org.elasticsearch.painless.MethodWriter; */ public final class ENull extends AExpression { - public ENull(final int line, final String location) { + public ENull(int line, String location) { super(line, location); } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { isNull = true; if (expected != null) { @@ -50,7 +49,7 @@ public final class ENull extends AExpression { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { adapter.visitInsn(Opcodes.ACONST_NULL); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java index 75f85703bc8..ee70bb77d44 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENumeric.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Sort; import org.elasticsearch.painless.Variables; @@ -33,7 +32,7 @@ public final class ENumeric extends AExpression { final String value; int radix; - public ENumeric(final int line, final String location, final String value, final int radix) { + public ENumeric(int line, String location, String value, int radix) { super(line, location); this.value = value; @@ -41,7 +40,7 @@ public final class ENumeric extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { if (value.endsWith("d") || value.endsWith("D")) { if (radix != 10) { throw new IllegalStateException(error("Invalid tree structure.")); @@ -96,7 +95,7 @@ public final class ENumeric extends AExpression { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { throw new IllegalArgumentException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java index 115db1499f4..353dc8ee885 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EUnary.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Sort; import org.elasticsearch.painless.Definition.Type; @@ -40,7 +39,7 @@ public final class EUnary extends AExpression { Operation operation; AExpression child; - public EUnary(final int line, final String location, final Operation operation, final AExpression child) { + public EUnary(int line, String location, Operation operation, AExpression child) { super(line, location); this.operation = operation; @@ -48,24 +47,24 @@ public final class EUnary extends AExpression { } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { if (operation == Operation.NOT) { - analyzeNot(settings, variables); + analyzeNot(variables); } else if (operation == Operation.BWNOT) { - analyzeBWNot(settings, variables); + analyzeBWNot(variables); } else if (operation == Operation.ADD) { - analyzerAdd(settings, variables); + analyzerAdd(variables); } else if (operation == Operation.SUB) { - analyzerSub(settings, variables); + analyzerSub(variables); } else { throw new IllegalStateException(error("Illegal tree structure.")); } } - void analyzeNot(final CompilerSettings settings, final Variables variables) { + void analyzeNot(Variables variables) { child.expected = Definition.BOOLEAN_TYPE; - child.analyze(settings, variables); - child = child.cast(settings, variables); + child.analyze(variables); + child = child.cast(variables); if (child.constant != null) { constant = !(boolean)child.constant; @@ -74,8 +73,8 @@ public final class EUnary extends AExpression { actual = Definition.BOOLEAN_TYPE; } - void analyzeBWNot(final CompilerSettings settings, final Variables variables) { - child.analyze(settings, variables); + void analyzeBWNot(Variables variables) { + child.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(child.actual, false, true); @@ -84,7 +83,7 @@ public final class EUnary extends AExpression { } child.expected = promote; - child = child.cast(settings, variables); + child = child.cast(variables); if (child.constant != null) { final Sort sort = promote.sort; @@ -101,8 +100,8 @@ public final class EUnary extends AExpression { actual = promote; } - void analyzerAdd(final CompilerSettings settings, final Variables variables) { - child.analyze(settings, variables); + void analyzerAdd(Variables variables) { + child.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(child.actual, true, true); @@ -111,7 +110,7 @@ public final class EUnary extends AExpression { } child.expected = promote; - child = child.cast(settings, variables); + child = child.cast(variables); if (child.constant != null) { final Sort sort = promote.sort; @@ -132,8 +131,8 @@ public final class EUnary extends AExpression { actual = promote; } - void analyzerSub(final CompilerSettings settings, final Variables variables) { - child.analyze(settings, variables); + void analyzerSub(Variables variables) { + child.analyze(variables); final Type promote = AnalyzerCaster.promoteNumeric(child.actual, true, true); @@ -142,7 +141,7 @@ public final class EUnary extends AExpression { } child.expected = promote; - child = child.cast(settings, variables); + child = child.cast(variables); if (child.constant != null) { final Sort sort = promote.sort; @@ -164,14 +163,14 @@ public final class EUnary extends AExpression { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { if (operation == Operation.NOT) { if (tru == null && fals == null) { final Label localfals = new Label(); final Label end = new Label(); child.fals = localfals; - child.write(settings, adapter); + child.write(adapter); adapter.push(false); adapter.goTo(end); @@ -181,13 +180,13 @@ public final class EUnary extends AExpression { } else { child.tru = fals; child.fals = tru; - child.write(settings, adapter); + child.write(adapter); } } else { final org.objectweb.asm.Type type = actual.type; final Sort sort = actual.sort; - child.write(settings, adapter); + child.write(adapter); if (operation == Operation.BWNOT) { if (sort == Sort.DEF) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java index 4678e9766f3..4a6df96073e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LArrayLength.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -31,14 +30,14 @@ public final class LArrayLength extends ALink { final String value; - LArrayLength(final int line, final String location, final String value) { + LArrayLength(int line, String location, String value) { super(line, location, -1); this.value = value; } @Override - ALink analyze(final CompilerSettings settings, final Variables variables) { + ALink analyze(Variables variables) { if ("length".equals(value)) { if (!load) { throw new IllegalArgumentException(error("Must read array field [length].")); @@ -55,17 +54,17 @@ public final class LArrayLength extends ALink { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { adapter.arrayLength(); } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { throw new IllegalStateException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java index 1a1d4b5927e..95cc02602f6 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LBrace.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Sort; import org.elasticsearch.painless.Variables; @@ -35,14 +34,14 @@ public final class LBrace extends ALink { AExpression index; - public LBrace(final int line, final String location, final AExpression index) { + public LBrace(int line, String location, AExpression index) { super(line, location, 2); this.index = index; } @Override - ALink analyze(final CompilerSettings settings, final Variables variables) { + ALink analyze(Variables variables) { if (before == null) { throw new IllegalStateException(error("Illegal tree structure.")); } @@ -51,35 +50,35 @@ public final class LBrace extends ALink { if (sort == Sort.ARRAY) { index.expected = Definition.INT_TYPE; - index.analyze(settings, variables); - index = index.cast(settings, variables); + index.analyze(variables); + index = index.cast(variables); after = Definition.getType(before.struct, before.dimensions - 1); return this; } else if (sort == Sort.DEF) { - return new LDefArray(line, location, index).copy(this).analyze(settings, variables); + return new LDefArray(line, location, index).copy(this).analyze(variables); } else if (Map.class.isAssignableFrom(before.clazz)) { - return new LMapShortcut(line, location, index).copy(this).analyze(settings, variables); + return new LMapShortcut(line, location, index).copy(this).analyze(variables); } else if (List.class.isAssignableFrom(before.clazz)) { - return new LListShortcut(line, location, index).copy(this).analyze(settings, variables); + return new LListShortcut(line, location, index).copy(this).analyze(variables); } throw new IllegalArgumentException(error("Illegal array access on type [" + before.name + "].")); } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { - index.write(settings, adapter); + void write(MethodWriter adapter) { + index.write(adapter); } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { adapter.arrayLoad(after.type); } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { adapter.arrayStore(after.type); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCall.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCall.java index 150c9097ddd..6ea2eb2d3b3 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCall.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCall.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Method; import org.elasticsearch.painless.Definition.Struct; @@ -38,7 +37,7 @@ public final class LCall extends ALink { Method method = null; - public LCall(final int line, final String location, final String name, final List arguments) { + public LCall(int line, String location, String name, List arguments) { super(line, location, -1); this.name = name; @@ -46,7 +45,7 @@ public final class LCall extends ALink { } @Override - ALink analyze(final CompilerSettings settings, final Variables variables) { + ALink analyze(Variables variables) { if (before == null) { throw new IllegalStateException(error("Illegal tree structure.")); } else if (before.sort == Definition.Sort.ARRAY) { @@ -64,8 +63,8 @@ public final class LCall extends ALink { final AExpression expression = arguments.get(argument); expression.expected = method.arguments.get(argument); - expression.analyze(settings, variables); - arguments.set(argument, expression.cast(settings, variables)); + expression.analyze(variables); + arguments.set(argument, expression.cast(variables)); } statement = true; @@ -76,7 +75,7 @@ public final class LCall extends ALink { final ALink link = new LDefCall(line, location, name, arguments); link.copy(this); - return link.analyze(settings, variables); + return link.analyze(variables); } throw new IllegalArgumentException(error("Unknown call [" + name + "] with [" + arguments.size() + @@ -84,14 +83,14 @@ public final class LCall extends ALink { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { for (final AExpression argument : arguments) { - argument.write(settings, adapter); + argument.write(adapter); } if (java.lang.reflect.Modifier.isStatic(method.reflect.getModifiers())) { @@ -108,7 +107,7 @@ public final class LCall extends ALink { } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { throw new IllegalStateException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java index f8a03085124..5650dd77b4e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LCast.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Cast; import org.elasticsearch.painless.AnalyzerCaster; @@ -35,14 +34,14 @@ public final class LCast extends ALink { Cast cast = null; - public LCast(final int line, final String location, final String type) { + public LCast(int line, String location, String type) { super(line, location, -1); this.type = type; } @Override - ALink analyze(final CompilerSettings settings, final Variables variables) { + ALink analyze(Variables variables) { if (before == null) { throw new IllegalStateException(error("Illegal tree structure.")); } else if (store) { @@ -61,17 +60,17 @@ public final class LCast extends ALink { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { adapter.writeCast(cast); } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { // Do nothing. } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { throw new IllegalStateException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java index e07dd9ab6ff..1ef12026e65 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefArray.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.DefBootstrap; import org.elasticsearch.painless.Variables; @@ -35,17 +34,17 @@ final class LDefArray extends ALink implements IDefLink { AExpression index; - LDefArray(final int line, final String location, final AExpression index) { + LDefArray(int line, String location, AExpression index) { super(line, location, 2); this.index = index; } @Override - ALink analyze(final CompilerSettings settings, final Variables variables) { - index.analyze(settings, variables); + ALink analyze(Variables variables) { + index.analyze(variables); index.expected = index.actual; - index = index.cast(settings, variables); + index = index.cast(variables); after = Definition.DEF_TYPE; @@ -53,18 +52,18 @@ final class LDefArray extends ALink implements IDefLink { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { - index.write(settings, adapter); + void write(MethodWriter adapter) { + index.write(adapter); } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { final String desc = Type.getMethodDescriptor(after.type, Definition.DEF_TYPE.type, index.actual.type); adapter.invokeDynamic("arrayLoad", desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.ARRAY_LOAD); } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { final String desc = Type.getMethodDescriptor(Definition.VOID_TYPE.type, Definition.DEF_TYPE.type, index.actual.type, after.type); adapter.invokeDynamic("arrayStore", desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.ARRAY_STORE); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java index f15f132cbec..f9ab0934eb5 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefCall.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.DefBootstrap; import org.elasticsearch.painless.Variables; @@ -37,7 +36,7 @@ final class LDefCall extends ALink implements IDefLink { final String name; final List arguments; - LDefCall(final int line, final String location, final String name, final List arguments) { + LDefCall(int line, String location, String name, List arguments) { super(line, location, -1); this.name = name; @@ -45,13 +44,13 @@ final class LDefCall extends ALink implements IDefLink { } @Override - ALink analyze(final CompilerSettings settings, final Variables variables) { + ALink analyze(Variables variables) { for (int argument = 0; argument < arguments.size(); ++argument) { final AExpression expression = arguments.get(argument); - expression.analyze(settings, variables); + expression.analyze(variables); expression.expected = expression.actual; - arguments.set(argument, expression.cast(settings, variables)); + arguments.set(argument, expression.cast(variables)); } statement = true; @@ -61,12 +60,12 @@ final class LDefCall extends ALink implements IDefLink { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { final StringBuilder signature = new StringBuilder(); signature.append('('); @@ -77,7 +76,7 @@ final class LDefCall extends ALink implements IDefLink { // it can avoid some unnecessary boxing etc. for (final AExpression argument : arguments) { signature.append(argument.actual.type.getDescriptor()); - argument.write(settings, adapter); + argument.write(adapter); } signature.append(')'); @@ -88,7 +87,7 @@ final class LDefCall extends ALink implements IDefLink { } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { throw new IllegalStateException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java index 84850826e6f..ee0cf990c5b 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LDefField.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.DefBootstrap; import org.elasticsearch.painless.Variables; @@ -35,7 +34,7 @@ final class LDefField extends ALink implements IDefLink { final String value; - LDefField(final int line, final String location, final String value) { + LDefField(int line, String location, String value) { super(line, location, 1); this.value = value; @@ -43,25 +42,25 @@ final class LDefField extends ALink implements IDefLink { @Override - ALink analyze(final CompilerSettings settings, final Variables variables) { + ALink analyze(Variables variables) { after = Definition.DEF_TYPE; return this; } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { final String desc = Type.getMethodDescriptor(after.type, Definition.DEF_TYPE.type); adapter.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.LOAD); } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { final String desc = Type.getMethodDescriptor(Definition.VOID_TYPE.type, Definition.DEF_TYPE.type, after.type); adapter.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, DefBootstrap.STORE); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LField.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LField.java index 3c0368666d0..44ba33acdda 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LField.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LField.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Field; import org.elasticsearch.painless.Definition.Sort; @@ -39,14 +38,14 @@ public final class LField extends ALink { Field field; - public LField(final int line, final String location, final String value) { + public LField(int line, String location, String value) { super(line, location, 1); this.value = value; } @Override - ALink analyze(CompilerSettings settings, Variables variables) { + ALink analyze(Variables variables) { if (before == null) { throw new IllegalStateException(error("Illegal tree structure.")); } @@ -54,9 +53,9 @@ public final class LField extends ALink { final Sort sort = before.sort; if (sort == Sort.ARRAY) { - return new LArrayLength(line, location, value).copy(this).analyze(settings, variables); + return new LArrayLength(line, location, value).copy(this).analyze(variables); } else if (sort == Sort.DEF) { - return new LDefField(line, location, value).copy(this).analyze(settings, variables); + return new LDefField(line, location, value).copy(this).analyze(variables); } final Struct struct = before.struct; @@ -80,17 +79,17 @@ public final class LField extends ALink { Character.toUpperCase(value.charAt(0)) + value.substring(1), 1)); if (shortcut) { - return new LShortcut(line, location, value).copy(this).analyze(settings, variables); + return new LShortcut(line, location, value).copy(this).analyze(variables); } else { final EConstant index = new EConstant(line, location, value); - index.analyze(settings, variables); + index.analyze(variables); if (Map.class.isAssignableFrom(before.clazz)) { - return new LMapShortcut(line, location, index).copy(this).analyze(settings, variables); + return new LMapShortcut(line, location, index).copy(this).analyze(variables); } if (List.class.isAssignableFrom(before.clazz)) { - return new LListShortcut(line, location, index).copy(this).analyze(settings, variables); + return new LListShortcut(line, location, index).copy(this).analyze(variables); } } } @@ -99,12 +98,12 @@ public final class LField extends ALink { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { if (java.lang.reflect.Modifier.isStatic(field.reflect.getModifiers())) { adapter.getStatic(field.owner.type, field.reflect.getName(), field.type.type); } else { @@ -113,7 +112,7 @@ public final class LField extends ALink { } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { if (java.lang.reflect.Modifier.isStatic(field.reflect.getModifiers())) { adapter.putStatic(field.owner.type, field.reflect.getName(), field.type.type); } else { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java index 9541459a615..52f82c9d1ca 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LListShortcut.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Method; import org.elasticsearch.painless.Definition.Sort; @@ -35,14 +34,14 @@ final class LListShortcut extends ALink { Method getter; Method setter; - LListShortcut(final int line, final String location, final AExpression index) { + LListShortcut(int line, String location, AExpression index) { super(line, location, 2); this.index = index; } @Override - ALink analyze(final CompilerSettings settings, final Variables variables) { + ALink analyze(Variables variables) { getter = before.struct.methods.get(new Definition.MethodKey("get", 1)); setter = before.struct.methods.get(new Definition.MethodKey("set", 2)); @@ -62,8 +61,8 @@ final class LListShortcut extends ALink { if ((load || store) && (!load || getter != null) && (!store || setter != null)) { index.expected = Definition.INT_TYPE; - index.analyze(settings, variables); - index = index.cast(settings, variables); + index.analyze(variables); + index = index.cast(variables); after = setter != null ? setter.arguments.get(1) : getter.rtn; } else { @@ -74,12 +73,12 @@ final class LListShortcut extends ALink { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { - index.write(settings, adapter); + void write(MethodWriter adapter) { + index.write(adapter); } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { if (java.lang.reflect.Modifier.isInterface(getter.owner.clazz.getModifiers())) { adapter.invokeInterface(getter.owner.type, getter.method); } else { @@ -92,7 +91,7 @@ final class LListShortcut extends ALink { } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { if (java.lang.reflect.Modifier.isInterface(setter.owner.clazz.getModifiers())) { adapter.invokeInterface(setter.owner.type, setter.method); } else { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LMapShortcut.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LMapShortcut.java index f06cb46152b..9fbc39d72b3 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LMapShortcut.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LMapShortcut.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Method; import org.elasticsearch.painless.Definition.Sort; @@ -35,14 +34,14 @@ final class LMapShortcut extends ALink { Method getter; Method setter; - LMapShortcut(final int line, final String location, final AExpression index) { + LMapShortcut(int line, String location, AExpression index) { super(line, location, 2); this.index = index; } @Override - ALink analyze(final CompilerSettings settings, final Variables variables) { + ALink analyze(Variables variables) { getter = before.struct.methods.get(new Definition.MethodKey("get", 1)); setter = before.struct.methods.get(new Definition.MethodKey("put", 2)); @@ -61,8 +60,8 @@ final class LMapShortcut extends ALink { if ((load || store) && (!load || getter != null) && (!store || setter != null)) { index.expected = setter != null ? setter.arguments.get(0) : getter.arguments.get(0); - index.analyze(settings, variables); - index = index.cast(settings, variables); + index.analyze(variables); + index = index.cast(variables); after = setter != null ? setter.arguments.get(1) : getter.rtn; } else { @@ -73,12 +72,12 @@ final class LMapShortcut extends ALink { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { - index.write(settings, adapter); + void write(MethodWriter adapter) { + index.write(adapter); } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { if (java.lang.reflect.Modifier.isInterface(getter.owner.clazz.getModifiers())) { adapter.invokeInterface(getter.owner.type, getter.method); } else { @@ -91,7 +90,7 @@ final class LMapShortcut extends ALink { } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { if (java.lang.reflect.Modifier.isInterface(setter.owner.clazz.getModifiers())) { adapter.invokeInterface(setter.owner.type, setter.method); } else { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java index 2faad220db6..da88b45e72d 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewArray.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Type; import org.elasticsearch.painless.Variables; @@ -35,7 +34,7 @@ public final class LNewArray extends ALink { final String type; final List arguments; - public LNewArray(final int line, final String location, final String type, final List arguments) { + public LNewArray(int line, String location, String type, List arguments) { super(line, location, -1); this.type = type; @@ -43,7 +42,7 @@ public final class LNewArray extends ALink { } @Override - ALink analyze(final CompilerSettings settings, final Variables variables) { + ALink analyze(Variables variables) { if (before != null) { throw new IllegalStateException(error("Illegal tree structure.")); } else if (store) { @@ -64,8 +63,8 @@ public final class LNewArray extends ALink { final AExpression expression = arguments.get(argument); expression.expected = Definition.INT_TYPE; - expression.analyze(settings, variables); - arguments.set(argument, expression.cast(settings, variables)); + expression.analyze(variables); + arguments.set(argument, expression.cast(variables)); } after = Definition.getType(type.struct, arguments.size()); @@ -74,14 +73,14 @@ public final class LNewArray extends ALink { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { for (final AExpression argument : arguments) { - argument.write(settings, adapter); + argument.write(adapter); } if (arguments.size() > 1) { @@ -92,7 +91,7 @@ public final class LNewArray extends ALink { } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { throw new IllegalStateException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java index a47ced1e096..ad3fc4627a5 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LNewObj.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Constructor; import org.elasticsearch.painless.Definition.Struct; @@ -39,7 +38,7 @@ public final class LNewObj extends ALink { Constructor constructor; - public LNewObj(final int line, final String location, final String type, final List arguments) { + public LNewObj(int line, String location, String type, List arguments) { super(line, location, -1); this.type = type; @@ -47,7 +46,7 @@ public final class LNewObj extends ALink { } @Override - ALink analyze(final CompilerSettings settings, final Variables variables) { + ALink analyze(Variables variables) { if (before != null) { throw new IllegalStateException(error("Illegal tree structure")); } else if (store) { @@ -78,8 +77,8 @@ public final class LNewObj extends ALink { final AExpression expression = arguments.get(argument); expression.expected = types[argument]; - expression.analyze(settings, variables); - arguments.set(argument, expression.cast(settings, variables)); + expression.analyze(variables); + arguments.set(argument, expression.cast(variables)); } statement = true; @@ -92,27 +91,27 @@ public final class LNewObj extends ALink { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { adapter.newInstance(after.type); if (load) { adapter.dup(); } - for (final AExpression argument : arguments) { - argument.write(settings, adapter); + for (AExpression argument : arguments) { + argument.write(adapter); } adapter.invokeConstructor(constructor.owner.type, constructor.method); } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { throw new IllegalStateException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LShortcut.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LShortcut.java index 79feef8813b..85a7d70c46e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LShortcut.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LShortcut.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Method; import org.elasticsearch.painless.Definition.Sort; @@ -37,14 +36,14 @@ final class LShortcut extends ALink { Method getter = null; Method setter = null; - LShortcut(final int line, final String location, final String value) { + LShortcut(int line, String location, String value) { super(line, location, 1); this.value = value; } @Override - ALink analyze(final CompilerSettings settings, final Variables variables) { + ALink analyze(Variables variables) { final Struct struct = before.struct; getter = struct.methods.get(new Definition.MethodKey("get" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 0)); @@ -74,12 +73,12 @@ final class LShortcut extends ALink { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { if (java.lang.reflect.Modifier.isInterface(getter.owner.clazz.getModifiers())) { adapter.invokeInterface(getter.owner.type, getter.method); } else { @@ -92,7 +91,7 @@ final class LShortcut extends ALink { } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { if (java.lang.reflect.Modifier.isInterface(setter.owner.clazz.getModifiers())) { adapter.invokeInterface(setter.owner.type, setter.method); } else { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java index 115c4c57ab3..07d76d42676 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LString.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -29,14 +28,14 @@ import org.elasticsearch.painless.MethodWriter; */ public final class LString extends ALink { - public LString(final int line, final String location, final String string) { + public LString(int line, String location, String string) { super(line, location, -1); this.string = string; } @Override - ALink analyze(final CompilerSettings settings, final Variables variables) { + ALink analyze(Variables variables) { if (before != null) { throw new IllegalStateException("Illegal tree structure."); } else if (store) { @@ -51,17 +50,17 @@ public final class LString extends ALink { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { adapter.push(string); } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { throw new IllegalStateException(error("Illegal tree structure.")); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LVariable.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LVariable.java index 6d4254f76ba..85a2048bdc6 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LVariable.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/LVariable.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Type; import org.elasticsearch.painless.Variables; @@ -36,14 +35,14 @@ public final class LVariable extends ALink { int slot; - public LVariable(final int line, final String location, final String name) { + public LVariable(int line, String location, String name) { super(line, location, 0); this.name = name; } @Override - ALink analyze(final CompilerSettings settings, final Variables variables) { + ALink analyze(Variables variables) { if (before != null) { throw new IllegalStateException(error("Illegal tree structure.")); } @@ -74,17 +73,17 @@ public final class LVariable extends ALink { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { // Do nothing. } @Override - void load(final CompilerSettings settings, final MethodWriter adapter) { + void load(MethodWriter adapter) { adapter.visitVarInsn(after.type.getOpcode(Opcodes.ILOAD), slot); } @Override - void store(final CompilerSettings settings, final MethodWriter adapter) { + void store(MethodWriter adapter) { adapter.visitVarInsn(after.type.getOpcode(Opcodes.ISTORE), slot); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBlock.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBlock.java index 7b9aed850b6..a925c411a2a 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBlock.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBlock.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -33,17 +32,17 @@ public final class SBlock extends AStatement { final List statements; - public SBlock(final int line, final String location, final List statements) { + public SBlock(int line, String location, List statements) { super(line, location); this.statements = Collections.unmodifiableList(statements); } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { final AStatement last = statements.get(statements.size() - 1); - for (final AStatement statement : statements) { + for (AStatement statement : statements) { if (allEscape) { throw new IllegalArgumentException(error("Unreachable statement.")); } @@ -52,7 +51,7 @@ public final class SBlock extends AStatement { statement.lastSource = lastSource && statement == last; statement.lastLoop = (beginLoop || lastLoop) && statement == last; - statement.analyze(settings, variables); + statement.analyze(variables); methodEscape = statement.methodEscape; loopEscape = statement.loopEscape; @@ -64,11 +63,11 @@ public final class SBlock extends AStatement { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { - for (final AStatement statement : statements) { + void write(MethodWriter adapter) { + for (AStatement statement : statements) { statement.continu = continu; statement.brake = brake; - statement.write(settings, adapter); + statement.write(adapter); } } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBreak.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBreak.java index 08f8e811b05..fb12a2b452e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBreak.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SBreak.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -28,12 +27,12 @@ import org.elasticsearch.painless.MethodWriter; */ public final class SBreak extends AStatement { - public SBreak(final int line, final String location) { + public SBreak(int line, String location) { super(line, location); } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { if (!inLoop) { throw new IllegalArgumentException(error("Break statement outside of a loop.")); } @@ -45,7 +44,7 @@ public final class SBreak extends AStatement { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { writeDebugInfo(adapter); adapter.goTo(brake); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SContinue.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SContinue.java index 35317e8de8a..01ca3f5697d 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SContinue.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SContinue.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -28,12 +27,12 @@ import org.elasticsearch.painless.MethodWriter; */ public final class SContinue extends AStatement { - public SContinue(final int line, final String location) { + public SContinue(int line, String location) { super(line, location); } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { if (!inLoop) { throw new IllegalArgumentException(error("Continue statement outside of a loop.")); } @@ -48,7 +47,7 @@ public final class SContinue extends AStatement { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { writeDebugInfo(adapter); adapter.goTo(continu); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclBlock.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclBlock.java index ee878146364..917dd9b8e5a 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclBlock.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclBlock.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -33,25 +32,25 @@ public final class SDeclBlock extends AStatement { final List declarations; - public SDeclBlock(final int line, final String location, final List declarations) { + public SDeclBlock(int line, String location, List declarations) { super(line, location); this.declarations = Collections.unmodifiableList(declarations); } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { for (final SDeclaration declaration : declarations) { - declaration.analyze(settings, variables); + declaration.analyze(variables); } statementCount = declarations.size(); } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { for (final SDeclaration declaration : declarations) { - declaration.write(settings, adapter); + declaration.write(adapter); } } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java index adf24509f6c..0e366dfc19b 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition.Sort; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.Variables.Variable; @@ -37,7 +36,7 @@ public final class SDeclaration extends AStatement { Variable variable; - public SDeclaration(final int line, final String location, final String type, final String name, final AExpression expression) { + public SDeclaration(int line, String location, String type, String name, AExpression expression) { super(line, location); this.type = type; @@ -46,18 +45,18 @@ public final class SDeclaration extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { variable = variables.addVariable(location, type, name, false, false); if (expression != null) { expression.expected = variable.type; - expression.analyze(settings, variables); - expression = expression.cast(settings, variables); + expression.analyze(variables); + expression = expression.cast(variables); } } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { writeDebugInfo(adapter); final org.objectweb.asm.Type type = variable.type.type; final Sort sort = variable.type.sort; @@ -65,7 +64,7 @@ public final class SDeclaration extends AStatement { final boolean initialize = expression == null; if (!initialize) { - expression.write(settings, adapter); + expression.write(adapter); } switch (sort) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java index 249ff75c744..6c8785a923a 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDo.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.objectweb.asm.Label; @@ -32,30 +31,32 @@ public final class SDo extends AStatement { final AStatement block; AExpression condition; + final int maxLoopCounter; - public SDo(final int line, final String location, final AStatement block, final AExpression condition) { + public SDo(int line, String location, AStatement block, AExpression condition, int maxLoopCounter) { super(line, location); this.condition = condition; this.block = block; + this.maxLoopCounter = maxLoopCounter; } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { variables.incrementScope(); block.beginLoop = true; block.inLoop = true; - block.analyze(settings, variables); + block.analyze(variables); if (block.loopEscape && !block.anyContinue) { throw new IllegalArgumentException(error("Extraneous do while loop.")); } condition.expected = Definition.BOOLEAN_TYPE; - condition.analyze(settings, variables); - condition = condition.cast(settings, variables); + condition.analyze(variables); + condition = condition.cast(variables); if (condition.constant != null) { final boolean continuous = (boolean)condition.constant; @@ -72,7 +73,7 @@ public final class SDo extends AStatement { statementCount = 1; - if (settings.getMaxLoopCounter() > 0) { + if (maxLoopCounter > 0) { loopCounterSlot = variables.getVariable(location, "#loop").slot; } @@ -80,7 +81,7 @@ public final class SDo extends AStatement { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { writeDebugInfo(adapter); final Label start = new Label(); final Label begin = new Label(); @@ -90,12 +91,12 @@ public final class SDo extends AStatement { block.continu = begin; block.brake = end; - block.write(settings, adapter); + block.write(adapter); adapter.mark(begin); condition.fals = end; - condition.write(settings, adapter); + condition.write(adapter); adapter.writeLoopCounter(loopCounterSlot, Math.max(1, block.statementCount)); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java index aaf63a3c923..46922fdcd9e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SExpression.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Definition.Sort; import org.elasticsearch.painless.Variables; @@ -32,16 +31,16 @@ public final class SExpression extends AStatement { AExpression expression; - public SExpression(final int line, final String location, final AExpression expression) { + public SExpression(int line, String location, AExpression expression) { super(line, location); this.expression = expression; } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { expression.read = lastSource; - expression.analyze(settings, variables); + expression.analyze(variables); if (!lastSource && !expression.statement) { throw new IllegalArgumentException(error("Not a statement.")); @@ -50,7 +49,7 @@ public final class SExpression extends AStatement { final boolean rtn = lastSource && expression.actual.sort != Sort.VOID; expression.expected = rtn ? Definition.OBJECT_TYPE : expression.actual; - expression = expression.cast(settings, variables); + expression = expression.cast(variables); methodEscape = rtn; loopEscape = rtn; @@ -59,9 +58,9 @@ public final class SExpression extends AStatement { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { writeDebugInfo(adapter); - expression.write(settings, adapter); + expression.write(adapter); if (methodEscape) { adapter.returnValue(); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java index cbce549f1cb..56073e6e8db 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFor.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.objectweb.asm.Label; @@ -34,31 +33,33 @@ public final class SFor extends AStatement { AExpression condition; AExpression afterthought; final AStatement block; + final int maxLoopCounter; - public SFor(final int line, final String location, - final ANode initializer, final AExpression condition, final AExpression afterthought, final AStatement block) { + public SFor(int line, String location, + ANode initializer, AExpression condition, AExpression afterthought, AStatement block, int maxLoopCounter) { super(line, location); this.initializer = initializer; this.condition = condition; this.afterthought = afterthought; this.block = block; + this.maxLoopCounter = maxLoopCounter; } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { variables.incrementScope(); boolean continuous = false; if (initializer != null) { if (initializer instanceof SDeclBlock) { - ((SDeclBlock)initializer).analyze(settings, variables); + ((SDeclBlock)initializer).analyze(variables); } else if (initializer instanceof AExpression) { final AExpression initializer = (AExpression)this.initializer; initializer.read = false; - initializer.analyze(settings, variables); + initializer.analyze(variables); if (!initializer.statement) { throw new IllegalArgumentException(initializer.error("Not a statement.")); @@ -71,8 +72,8 @@ public final class SFor extends AStatement { if (condition != null) { condition.expected = Definition.BOOLEAN_TYPE; - condition.analyze(settings, variables); - condition = condition.cast(settings, variables); + condition.analyze(variables); + condition = condition.cast(variables); if (condition.constant != null) { continuous = (boolean)condition.constant; @@ -91,7 +92,7 @@ public final class SFor extends AStatement { if (afterthought != null) { afterthought.read = false; - afterthought.analyze(settings, variables); + afterthought.analyze(variables); if (!afterthought.statement) { throw new IllegalArgumentException(afterthought.error("Not a statement.")); @@ -104,7 +105,7 @@ public final class SFor extends AStatement { block.beginLoop = true; block.inLoop = true; - block.analyze(settings, variables); + block.analyze(variables); if (block.loopEscape && !block.anyContinue) { throw new IllegalArgumentException(error("Extraneous for loop.")); @@ -120,7 +121,7 @@ public final class SFor extends AStatement { statementCount = 1; - if (settings.getMaxLoopCounter() > 0) { + if (maxLoopCounter > 0) { loopCounterSlot = variables.getVariable(location, "#loop").slot; } @@ -128,18 +129,18 @@ public final class SFor extends AStatement { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { writeDebugInfo(adapter); final Label start = new Label(); final Label begin = afterthought == null ? start : new Label(); final Label end = new Label(); if (initializer instanceof SDeclBlock) { - ((SDeclBlock)initializer).write(settings, adapter); + ((SDeclBlock)initializer).write(adapter); } else if (initializer instanceof AExpression) { AExpression initializer = (AExpression)this.initializer; - initializer.write(settings, adapter); + initializer.write(adapter); adapter.writePop(initializer.expected.sort.size); } @@ -147,7 +148,7 @@ public final class SFor extends AStatement { if (condition != null) { condition.fals = end; - condition.write(settings, adapter); + condition.write(adapter); } boolean allEscape = false; @@ -162,14 +163,14 @@ public final class SFor extends AStatement { } adapter.writeLoopCounter(loopCounterSlot, statementCount); - block.write(settings, adapter); + block.write(adapter); } else { adapter.writeLoopCounter(loopCounterSlot, 1); } if (afterthought != null) { adapter.mark(begin); - afterthought.write(settings, adapter); + afterthought.write(adapter); } if (afterthought != null || !allEscape) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java index 1fadc4f0ac4..560ce44e415 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SIfElse.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.objectweb.asm.Label; @@ -34,8 +33,7 @@ public final class SIfElse extends AStatement { final AStatement ifblock; final AStatement elseblock; - public SIfElse(final int line, final String location, - final AExpression condition, final AStatement ifblock, final AStatement elseblock) { + public SIfElse(int line, String location, AExpression condition, AStatement ifblock, AStatement elseblock) { super(line, location); this.condition = condition; @@ -44,10 +42,10 @@ public final class SIfElse extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { condition.expected = Definition.BOOLEAN_TYPE; - condition.analyze(settings, variables); - condition = condition.cast(settings, variables); + condition.analyze(variables); + condition = condition.cast(variables); if (condition.constant != null) { throw new IllegalArgumentException(error("Extraneous if statement.")); @@ -58,7 +56,7 @@ public final class SIfElse extends AStatement { ifblock.lastLoop = lastLoop; variables.incrementScope(); - ifblock.analyze(settings, variables); + ifblock.analyze(variables); variables.decrementScope(); anyContinue = ifblock.anyContinue; @@ -71,7 +69,7 @@ public final class SIfElse extends AStatement { elseblock.lastLoop = lastLoop; variables.incrementScope(); - elseblock.analyze(settings, variables); + elseblock.analyze(variables); variables.decrementScope(); methodEscape = ifblock.methodEscape && elseblock.methodEscape; @@ -84,17 +82,17 @@ public final class SIfElse extends AStatement { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { writeDebugInfo(adapter); final Label end = new Label(); final Label fals = elseblock != null ? new Label() : end; condition.fals = fals; - condition.write(settings, adapter); + condition.write(adapter); ifblock.continu = continu; ifblock.brake = brake; - ifblock.write(settings, adapter); + ifblock.write(adapter); if (elseblock != null) { if (!ifblock.allEscape) { @@ -105,7 +103,7 @@ public final class SIfElse extends AStatement { elseblock.continu = continu; elseblock.brake = brake; - elseblock.write(settings, adapter); + elseblock.write(adapter); } adapter.mark(end); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java index f2c051ac1f6..d8c388e7e60 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SReturn.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -31,17 +30,17 @@ public final class SReturn extends AStatement { AExpression expression; - public SReturn(final int line, final String location, final AExpression expression) { + public SReturn(int line, String location, AExpression expression) { super(line, location); this.expression = expression; } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { expression.expected = Definition.OBJECT_TYPE; - expression.analyze(settings, variables); - expression = expression.cast(settings, variables); + expression.analyze(variables); + expression = expression.cast(variables); methodEscape = true; loopEscape = true; @@ -51,9 +50,9 @@ public final class SReturn extends AStatement { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { writeDebugInfo(adapter); - expression.write(settings, adapter); + expression.write(adapter); adapter.returnValue(); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSource.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSource.java index e77ce8330a6..0932ae6e2f0 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSource.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSource.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Variables; import org.objectweb.asm.Opcodes; import org.elasticsearch.painless.MethodWriter; @@ -34,14 +33,14 @@ public final class SSource extends AStatement { final List statements; - public SSource(final int line, final String location, final List statements) { + public SSource(int line, String location, List statements) { super(line, location); this.statements = Collections.unmodifiableList(statements); } @Override - public void analyze(final CompilerSettings settings, final Variables variables) { + public void analyze(Variables variables) { variables.incrementScope(); final AStatement last = statements.get(statements.size() - 1); @@ -52,7 +51,7 @@ public final class SSource extends AStatement { } statement.lastSource = statement == last; - statement.analyze(settings, variables); + statement.analyze(variables); methodEscape = statement.methodEscape; allEscape = statement.allEscape; @@ -62,9 +61,9 @@ public final class SSource extends AStatement { } @Override - public void write(final CompilerSettings settings, final MethodWriter adapter) { + public void write(MethodWriter adapter) { for (final AStatement statement : statements) { - statement.write(settings, adapter); + statement.write(adapter); } if (!methodEscape) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java index f9a719a5f77..a0bfa12e267 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SThrow.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.MethodWriter; @@ -31,17 +30,17 @@ public final class SThrow extends AStatement { AExpression expression; - public SThrow(final int line, final String location, final AExpression expression) { + public SThrow(int line, String location, AExpression expression) { super(line, location); this.expression = expression; } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { expression.expected = Definition.EXCEPTION_TYPE; - expression.analyze(settings, variables); - expression = expression.cast(settings, variables); + expression.analyze(variables); + expression = expression.cast(variables); methodEscape = true; loopEscape = true; @@ -50,9 +49,9 @@ public final class SThrow extends AStatement { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { writeDebugInfo(adapter); - expression.write(settings, adapter); + expression.write(adapter); adapter.throwException(); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STrap.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STrap.java index a1ee15a050f..9a791b1615d 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STrap.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STrap.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Variables; import org.elasticsearch.painless.Variables.Variable; import org.objectweb.asm.Label; @@ -41,7 +40,7 @@ public final class STrap extends AStatement { Label end; Label exception; - public STrap(final int line, final String location, final String type, final String name, final AStatement block) { + public STrap(int line, String location, String type, String name, AStatement block) { super(line, location); this.type = type; @@ -50,7 +49,7 @@ public final class STrap extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { variable = variables.addVariable(location, type, name, true, false); if (!Exception.class.isAssignableFrom(variable.type.clazz)) { @@ -62,7 +61,7 @@ public final class STrap extends AStatement { block.inLoop = inLoop; block.lastLoop = lastLoop; - block.analyze(settings, variables); + block.analyze(variables); methodEscape = block.methodEscape; loopEscape = block.loopEscape; @@ -74,7 +73,7 @@ public final class STrap extends AStatement { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { writeDebugInfo(adapter); final Label jump = new Label(); @@ -84,7 +83,7 @@ public final class STrap extends AStatement { if (block != null) { block.continu = continu; block.brake = brake; - block.write(settings, adapter); + block.write(adapter); } adapter.visitTryCatchBlock(begin, end, jump, variable.type.type.getInternalName()); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STry.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STry.java index 70a5b2164da..4f97d5835cc 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STry.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/STry.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Variables; import org.objectweb.asm.Label; import org.elasticsearch.painless.MethodWriter; @@ -35,7 +34,7 @@ public final class STry extends AStatement { final AStatement block; final List traps; - public STry(final int line, final String location, final AStatement block, final List traps) { + public STry(int line, String location, AStatement block, List traps) { super(line, location); this.block = block; @@ -43,13 +42,13 @@ public final class STry extends AStatement { } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { block.lastSource = lastSource; block.inLoop = inLoop; block.lastLoop = lastLoop; variables.incrementScope(); - block.analyze(settings, variables); + block.analyze(variables); variables.decrementScope(); methodEscape = block.methodEscape; @@ -66,7 +65,7 @@ public final class STry extends AStatement { trap.lastLoop = lastLoop; variables.incrementScope(); - trap.analyze(settings, variables); + trap.analyze(variables); variables.decrementScope(); methodEscape &= trap.methodEscape; @@ -82,7 +81,7 @@ public final class STry extends AStatement { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { writeDebugInfo(adapter); final Label begin = new Label(); final Label end = new Label(); @@ -92,7 +91,7 @@ public final class STry extends AStatement { block.continu = continu; block.brake = brake; - block.write(settings, adapter); + block.write(adapter); if (!block.allEscape) { adapter.goTo(exception); @@ -104,7 +103,7 @@ public final class STry extends AStatement { trap.begin = begin; trap.end = end; trap.exception = traps.size() > 1 ? exception : null; - trap.write(settings, adapter); + trap.write(adapter); } if (!block.allEscape || traps.size() > 1) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java index 98616d11499..48f59c55189 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SWhile.java @@ -19,7 +19,6 @@ package org.elasticsearch.painless.node; -import org.elasticsearch.painless.CompilerSettings; import org.elasticsearch.painless.Definition; import org.elasticsearch.painless.Variables; import org.objectweb.asm.Label; @@ -32,21 +31,23 @@ public final class SWhile extends AStatement { AExpression condition; final AStatement block; + final int maxLoopCounter; - public SWhile(final int line, final String location, final AExpression condition, final AStatement block) { + public SWhile(int line, String location, AExpression condition, AStatement block, int maxLoopCounter) { super(line, location); this.condition = condition; this.block = block; + this.maxLoopCounter = maxLoopCounter; } @Override - void analyze(final CompilerSettings settings, final Variables variables) { + void analyze(Variables variables) { variables.incrementScope(); condition.expected = Definition.BOOLEAN_TYPE; - condition.analyze(settings, variables); - condition = condition.cast(settings, variables); + condition.analyze(variables); + condition = condition.cast(variables); boolean continuous = false; @@ -68,7 +69,7 @@ public final class SWhile extends AStatement { block.beginLoop = true; block.inLoop = true; - block.analyze(settings, variables); + block.analyze(variables); if (block.loopEscape && !block.anyContinue) { throw new IllegalArgumentException(error("Extranous while loop.")); @@ -84,7 +85,7 @@ public final class SWhile extends AStatement { statementCount = 1; - if (settings.getMaxLoopCounter() > 0) { + if (maxLoopCounter > 0) { loopCounterSlot = variables.getVariable(location, "#loop").slot; } @@ -92,7 +93,7 @@ public final class SWhile extends AStatement { } @Override - void write(final CompilerSettings settings, final MethodWriter adapter) { + void write(MethodWriter adapter) { writeDebugInfo(adapter); final Label begin = new Label(); final Label end = new Label(); @@ -100,14 +101,14 @@ public final class SWhile extends AStatement { adapter.mark(begin); condition.fals = end; - condition.write(settings, adapter); + condition.write(adapter); if (block != null) { adapter.writeLoopCounter(loopCounterSlot, Math.max(1, block.statementCount)); block.continu = begin; block.brake = end; - block.write(settings, adapter); + block.write(adapter); } else { adapter.writeLoopCounter(loopCounterSlot, 1); } From 2b793c1e06766aebb930b2ad226ae3d81beb8cd3 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Fri, 20 May 2016 10:38:06 -0700 Subject: [PATCH 19/22] Fix boxing. --- .../elasticsearch/painless/MethodWriter.java | 32 +++++++++++++++++++ .../painless/WriterConstants.java | 19 +++++++++++ .../elasticsearch/painless/BasicAPITests.java | 24 ++++++++++---- .../painless/DefOperationTests.java | 4 +-- .../elasticsearch/painless/EqualsTests.java | 4 +-- 5 files changed, 72 insertions(+), 11 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java index d17330eea8f..757041429a4 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java @@ -33,6 +33,12 @@ import java.util.ArrayList; import java.util.Deque; import java.util.List; +import static org.elasticsearch.painless.WriterConstants.BOOLEAN_OBJECT; +import static org.elasticsearch.painless.WriterConstants.BOOLEAN_VALUE_OF; +import static org.elasticsearch.painless.WriterConstants.BYTE_OBJECT; +import static org.elasticsearch.painless.WriterConstants.BYTE_VALUE_OF; +import static org.elasticsearch.painless.WriterConstants.CHARACTER_OBJECT; +import static org.elasticsearch.painless.WriterConstants.CHARACTER_VALUE_OF; import static org.elasticsearch.painless.WriterConstants.CHAR_TO_STRING; import static org.elasticsearch.painless.WriterConstants.DEF_ADD_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_AND_CALL; @@ -61,9 +67,19 @@ import static org.elasticsearch.painless.WriterConstants.DEF_TO_SHORT_IMPLICIT; import static org.elasticsearch.painless.WriterConstants.DEF_UTIL_TYPE; import static org.elasticsearch.painless.WriterConstants.DEF_USH_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_XOR_CALL; +import static org.elasticsearch.painless.WriterConstants.DOUBLE_OBJECT; +import static org.elasticsearch.painless.WriterConstants.DOUBLE_VALUE_OF; +import static org.elasticsearch.painless.WriterConstants.FLOAT_OBJECT; +import static org.elasticsearch.painless.WriterConstants.FLOAT_VALUE_OF; import static org.elasticsearch.painless.WriterConstants.INDY_STRING_CONCAT_BOOTSTRAP_HANDLE; +import static org.elasticsearch.painless.WriterConstants.INTEGER_OBJECT; +import static org.elasticsearch.painless.WriterConstants.INTEGER_VALUE_OF; +import static org.elasticsearch.painless.WriterConstants.LONG_OBJECT; +import static org.elasticsearch.painless.WriterConstants.LONG_VALUE_OF; import static org.elasticsearch.painless.WriterConstants.MAX_INDY_STRING_CONCAT_ARGS; import static org.elasticsearch.painless.WriterConstants.PAINLESS_ERROR_TYPE; +import static org.elasticsearch.painless.WriterConstants.SHORT_OBJECT; +import static org.elasticsearch.painless.WriterConstants.SHORT_VALUE_OF; import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_APPEND_BOOLEAN; import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_APPEND_CHAR; import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_APPEND_DOUBLE; @@ -184,6 +200,22 @@ public final class MethodWriter extends GeneratorAdapter { } } + @Override + public void box(final org.objectweb.asm.Type type) { + switch (type.getSort()) { + case org.objectweb.asm.Type.BOOLEAN: invokeStatic(BOOLEAN_OBJECT , BOOLEAN_VALUE_OF); break; + case org.objectweb.asm.Type.BYTE: invokeStatic(BYTE_OBJECT , BYTE_VALUE_OF); break; + case org.objectweb.asm.Type.SHORT: invokeStatic(SHORT_OBJECT , SHORT_VALUE_OF); break; + case org.objectweb.asm.Type.CHAR: invokeStatic(CHARACTER_OBJECT, CHARACTER_VALUE_OF); break; + case org.objectweb.asm.Type.INT: invokeStatic(INTEGER_OBJECT , INTEGER_VALUE_OF); break; + case org.objectweb.asm.Type.LONG: invokeStatic(LONG_OBJECT , LONG_VALUE_OF); break; + case org.objectweb.asm.Type.FLOAT: invokeStatic(FLOAT_OBJECT , FLOAT_VALUE_OF); break; + case org.objectweb.asm.Type.DOUBLE: invokeStatic(DOUBLE_OBJECT , DOUBLE_VALUE_OF); break; + default: + throw new IllegalArgumentException("Illegal tree structure."); + } + } + public void writeBranch(final Label tru, final Label fals) { if (tru != null) { visitJumpInsn(Opcodes.IFNE, tru); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java index b50ec7b8040..c9d24212bbc 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java @@ -138,6 +138,25 @@ public final class WriterConstants { public final static Method CHECKEQUALS = getAsmMethod(boolean.class, "checkEquals", Object.class, Object.class); + public final static Type BOOLEAN_OBJECT = Type.getType(Boolean.class); + public final static Type BYTE_OBJECT = Type.getType(Byte.class); + public final static Type SHORT_OBJECT = Type.getType(Short.class); + public final static Type CHARACTER_OBJECT = Type.getType(Character.class); + public final static Type INTEGER_OBJECT = Type.getType(Integer.class); + public final static Type LONG_OBJECT = Type.getType(Long.class); + public final static Type FLOAT_OBJECT = Type.getType(Float.class); + public final static Type DOUBLE_OBJECT = Type.getType(Double.class); + + /** box methods to replace the GeneratorAdapter's slow way of boxing */ + public final static Method BOOLEAN_VALUE_OF = getAsmMethod(Boolean.class , "valueOf", boolean.class); + public final static Method BYTE_VALUE_OF = getAsmMethod(Byte.class , "valueOf", byte.class); + public final static Method SHORT_VALUE_OF = getAsmMethod(Short.class , "valueOf", short.class); + public final static Method CHARACTER_VALUE_OF = getAsmMethod(Character.class, "valueOf", char.class); + public final static Method INTEGER_VALUE_OF = getAsmMethod(Integer.class , "valueOf", int.class); + public final static Method LONG_VALUE_OF = getAsmMethod(Long.class , "valueOf", long.class); + public final static Method FLOAT_VALUE_OF = getAsmMethod(Float.class , "valueOf", float.class); + public final static Method DOUBLE_VALUE_OF = getAsmMethod(Double.class , "valueOf", double.class); + private static Method getAsmMethod(final Class rtype, final String name, final Class... ptypes) { return new Method(name, MethodType.methodType(rtype, ptypes).toMethodDescriptorString()); } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicAPITests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicAPITests.java index b7479b505fe..338e3f00113 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicAPITests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/BasicAPITests.java @@ -45,39 +45,49 @@ public class BasicAPITests extends ScriptTestCase { assertEquals(3, exec("Map x = new HashMap(); x.put(2, 2); x.put(3, 3); x.put(-2, -2); Iterator y = x.values().iterator(); " + "int total = 0; while (y.hasNext()) total += (int)y.next(); return total;")); } - + /** Test loads and stores with a map */ public void testMapLoadStore() { assertEquals(5, exec("def x = new HashMap(); x.abc = 5; return x.abc;")); assertEquals(5, exec("def x = new HashMap(); x['abc'] = 5; return x['abc'];")); } - + /** Test loads and stores with a list */ public void testListLoadStore() { assertEquals(5, exec("def x = new ArrayList(); x.add(3); x.0 = 5; return x.0;")); assertEquals(5, exec("def x = new ArrayList(); x.add(3); x[0] = 5; return x[0];")); } - + /** Test shortcut for getters with isXXXX */ public void testListEmpty() { assertEquals(true, exec("def x = new ArrayList(); return x.empty;")); assertEquals(true, exec("def x = new HashMap(); return x.empty;")); } - + /** Test list method invocation */ public void testListGet() { assertEquals(5, exec("def x = new ArrayList(); x.add(5); return x.get(0);")); assertEquals(5, exec("def x = new ArrayList(); x.add(5); def index = 0; return x.get(index);")); } - + public void testListAsArray() { assertEquals(1, exec("def x = new ArrayList(); x.add(5); return x.length")); assertEquals(5, exec("def x = new ArrayList(); x.add(5); return x[0]")); assertEquals(1, exec("List x = new ArrayList(); x.add('Hallo'); return x.length")); } - + public void testDefAssignments() { assertEquals(2, exec("int x; def y = 2.0; x = (int)y;")); } - + + public void testInternalBoxing() { + assertBytecodeExists("def x = true", "INVOKESTATIC java/lang/Boolean.valueOf (Z)Ljava/lang/Boolean;"); + assertBytecodeExists("def x = (byte)1", "INVOKESTATIC java/lang/Byte.valueOf (B)Ljava/lang/Byte;"); + assertBytecodeExists("def x = (short)1", "INVOKESTATIC java/lang/Short.valueOf (S)Ljava/lang/Short;"); + assertBytecodeExists("def x = (char)1", "INVOKESTATIC java/lang/Character.valueOf (C)Ljava/lang/Character;"); + assertBytecodeExists("def x = 1", "INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;"); + assertBytecodeExists("def x = 1L", "INVOKESTATIC java/lang/Long.valueOf (J)Ljava/lang/Long;"); + assertBytecodeExists("def x = 1F", "INVOKESTATIC java/lang/Float.valueOf (F)Ljava/lang/Float;"); + assertBytecodeExists("def x = 1D", "INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;"); + } } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefOperationTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefOperationTests.java index 1b548efa3b8..9f171a96889 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefOperationTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefOperationTests.java @@ -799,7 +799,7 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(false, exec("def x = (byte)7; def y = (int)7; return x === y")); assertEquals(false, exec("def x = (short)6; def y = (int)6; return x === y")); assertEquals(false, exec("def x = (char)5; def y = (int)5; return x === y")); - assertEquals(false, exec("def x = (int)4; def y = (int)4; return x === y")); + assertEquals(true, exec("def x = (int)4; def y = (int)4; return x === y")); assertEquals(false, exec("def x = (long)5; def y = (int)3; return x === y")); assertEquals(false, exec("def x = (float)6; def y = (int)2; return x === y")); assertEquals(false, exec("def x = (double)7; def y = (int)1; return x === y")); @@ -837,7 +837,7 @@ public class DefOperationTests extends ScriptTestCase { assertEquals(true, exec("def x = (byte)7; def y = (int)7; return x !== y")); assertEquals(true, exec("def x = (short)6; def y = (int)6; return x !== y")); assertEquals(true, exec("def x = (char)5; def y = (int)5; return x !== y")); - assertEquals(true, exec("def x = (int)4; def y = (int)4; return x !== y")); + assertEquals(false, exec("def x = (int)4; def y = (int)4; return x !== y")); assertEquals(true, exec("def x = (long)5; def y = (int)3; return x !== y")); assertEquals(true, exec("def x = (float)6; def y = (int)2; return x !== y")); assertEquals(true, exec("def x = (double)7; def y = (int)1; return x !== y")); diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java index 59f9aadc6aa..cc308c70ded 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java @@ -118,7 +118,7 @@ public class EqualsTests extends ScriptTestCase { public void testBranchEquals() { assertEquals(0, exec("def a = (char)'a'; def b = (char)'b'; if (a == b) return 1; else return 0;")); assertEquals(1, exec("def a = (char)'a'; def b = (char)'a'; if (a == b) return 1; else return 0;")); - assertEquals(0, exec("def a = 1; def b = 1; if (a === b) return 1; else return 0;")); + assertEquals(1, exec("def a = 1; def b = 1; if (a === b) return 1; else return 0;")); assertEquals(0, exec("def a = (char)'a'; def b = (char)'a'; if (a === b) return 1; else return 0;")); assertEquals(1, exec("def a = (char)'a'; Object b = a; if (a === b) return 1; else return 0;")); assertEquals(1, exec("def a = 1; Number b = a; Number c = a; if (c === b) return 1; else return 0;")); @@ -128,7 +128,7 @@ public class EqualsTests extends ScriptTestCase { public void testBranchNotEquals() { assertEquals(1, exec("def a = (char)'a'; def b = (char)'b'; if (a != b) return 1; else return 0;")); assertEquals(0, exec("def a = (char)'a'; def b = (char)'a'; if (a != b) return 1; else return 0;")); - assertEquals(1, exec("def a = 1; def b = 1; if (a !== b) return 1; else return 0;")); + assertEquals(0, exec("def a = 1; def b = 1; if (a !== b) return 1; else return 0;")); assertEquals(1, exec("def a = (char)'a'; def b = (char)'a'; if (a !== b) return 1; else return 0;")); assertEquals(0, exec("def a = (char)'a'; Object b = a; if (a !== b) return 1; else return 0;")); assertEquals(0, exec("def a = 1; Number b = a; Number c = a; if (c !== b) return 1; else return 0;")); From d836194095a3be1eee117d9303a7055db8feedb9 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Fri, 20 May 2016 11:04:09 -0700 Subject: [PATCH 20/22] Fixed tests and added a comment to the box method. --- .../java/org/elasticsearch/painless/MethodWriter.java | 8 ++++++-- .../test/java/org/elasticsearch/painless/EqualsTests.java | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java index 757041429a4..b03de2ef4df 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java @@ -200,9 +200,15 @@ public final class MethodWriter extends GeneratorAdapter { } } + /** + * ASM does boxing in an evil way to be compatible with Java prior to verison 5. + * Supporting versions prior to 5 is not a requirement of this project, so the modern + * boxing methods are used instead. + */ @Override public void box(final org.objectweb.asm.Type type) { switch (type.getSort()) { + case org.objectweb.asm.Type.VOID: visitInsn(Opcodes.ACONST_NULL); break; case org.objectweb.asm.Type.BOOLEAN: invokeStatic(BOOLEAN_OBJECT , BOOLEAN_VALUE_OF); break; case org.objectweb.asm.Type.BYTE: invokeStatic(BYTE_OBJECT , BYTE_VALUE_OF); break; case org.objectweb.asm.Type.SHORT: invokeStatic(SHORT_OBJECT , SHORT_VALUE_OF); break; @@ -211,8 +217,6 @@ public final class MethodWriter extends GeneratorAdapter { case org.objectweb.asm.Type.LONG: invokeStatic(LONG_OBJECT , LONG_VALUE_OF); break; case org.objectweb.asm.Type.FLOAT: invokeStatic(FLOAT_OBJECT , FLOAT_VALUE_OF); break; case org.objectweb.asm.Type.DOUBLE: invokeStatic(DOUBLE_OBJECT , DOUBLE_VALUE_OF); break; - default: - throw new IllegalArgumentException("Illegal tree structure."); } } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java index cc308c70ded..7e4448495a9 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/EqualsTests.java @@ -119,7 +119,7 @@ public class EqualsTests extends ScriptTestCase { assertEquals(0, exec("def a = (char)'a'; def b = (char)'b'; if (a == b) return 1; else return 0;")); assertEquals(1, exec("def a = (char)'a'; def b = (char)'a'; if (a == b) return 1; else return 0;")); assertEquals(1, exec("def a = 1; def b = 1; if (a === b) return 1; else return 0;")); - assertEquals(0, exec("def a = (char)'a'; def b = (char)'a'; if (a === b) return 1; else return 0;")); + assertEquals(1, exec("def a = (char)'a'; def b = (char)'a'; if (a === b) return 1; else return 0;")); assertEquals(1, exec("def a = (char)'a'; Object b = a; if (a === b) return 1; else return 0;")); assertEquals(1, exec("def a = 1; Number b = a; Number c = a; if (c === b) return 1; else return 0;")); assertEquals(0, exec("def a = 1; Object b = new HashMap(); if (a === (Object)b) return 1; else return 0;")); @@ -129,7 +129,7 @@ public class EqualsTests extends ScriptTestCase { assertEquals(1, exec("def a = (char)'a'; def b = (char)'b'; if (a != b) return 1; else return 0;")); assertEquals(0, exec("def a = (char)'a'; def b = (char)'a'; if (a != b) return 1; else return 0;")); assertEquals(0, exec("def a = 1; def b = 1; if (a !== b) return 1; else return 0;")); - assertEquals(1, exec("def a = (char)'a'; def b = (char)'a'; if (a !== b) return 1; else return 0;")); + assertEquals(0, exec("def a = (char)'a'; def b = (char)'a'; if (a !== b) return 1; else return 0;")); assertEquals(0, exec("def a = (char)'a'; Object b = a; if (a !== b) return 1; else return 0;")); assertEquals(0, exec("def a = 1; Number b = a; Number c = a; if (c !== b) return 1; else return 0;")); assertEquals(1, exec("def a = 1; Object b = new HashMap(); if (a !== (Object)b) return 1; else return 0;")); From 0e24ed49e699e4aa6890daaaf720ee5cc3a6f5e8 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Fri, 20 May 2016 11:13:43 -0700 Subject: [PATCH 21/22] Use the build-in valueOf method instead of the custom one. --- .../elasticsearch/painless/MethodWriter.java | 42 ++----------------- .../painless/WriterConstants.java | 10 ----- 2 files changed, 3 insertions(+), 49 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java index b03de2ef4df..f0477478fda 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java @@ -33,12 +33,6 @@ import java.util.ArrayList; import java.util.Deque; import java.util.List; -import static org.elasticsearch.painless.WriterConstants.BOOLEAN_OBJECT; -import static org.elasticsearch.painless.WriterConstants.BOOLEAN_VALUE_OF; -import static org.elasticsearch.painless.WriterConstants.BYTE_OBJECT; -import static org.elasticsearch.painless.WriterConstants.BYTE_VALUE_OF; -import static org.elasticsearch.painless.WriterConstants.CHARACTER_OBJECT; -import static org.elasticsearch.painless.WriterConstants.CHARACTER_VALUE_OF; import static org.elasticsearch.painless.WriterConstants.CHAR_TO_STRING; import static org.elasticsearch.painless.WriterConstants.DEF_ADD_CALL; import static org.elasticsearch.painless.WriterConstants.DEF_AND_CALL; @@ -64,22 +58,12 @@ import static org.elasticsearch.painless.WriterConstants.DEF_TO_LONG_EXPLICIT; import static org.elasticsearch.painless.WriterConstants.DEF_TO_LONG_IMPLICIT; import static org.elasticsearch.painless.WriterConstants.DEF_TO_SHORT_EXPLICIT; import static org.elasticsearch.painless.WriterConstants.DEF_TO_SHORT_IMPLICIT; -import static org.elasticsearch.painless.WriterConstants.DEF_UTIL_TYPE; import static org.elasticsearch.painless.WriterConstants.DEF_USH_CALL; +import static org.elasticsearch.painless.WriterConstants.DEF_UTIL_TYPE; import static org.elasticsearch.painless.WriterConstants.DEF_XOR_CALL; -import static org.elasticsearch.painless.WriterConstants.DOUBLE_OBJECT; -import static org.elasticsearch.painless.WriterConstants.DOUBLE_VALUE_OF; -import static org.elasticsearch.painless.WriterConstants.FLOAT_OBJECT; -import static org.elasticsearch.painless.WriterConstants.FLOAT_VALUE_OF; import static org.elasticsearch.painless.WriterConstants.INDY_STRING_CONCAT_BOOTSTRAP_HANDLE; -import static org.elasticsearch.painless.WriterConstants.INTEGER_OBJECT; -import static org.elasticsearch.painless.WriterConstants.INTEGER_VALUE_OF; -import static org.elasticsearch.painless.WriterConstants.LONG_OBJECT; -import static org.elasticsearch.painless.WriterConstants.LONG_VALUE_OF; import static org.elasticsearch.painless.WriterConstants.MAX_INDY_STRING_CONCAT_ARGS; import static org.elasticsearch.painless.WriterConstants.PAINLESS_ERROR_TYPE; -import static org.elasticsearch.painless.WriterConstants.SHORT_OBJECT; -import static org.elasticsearch.painless.WriterConstants.SHORT_VALUE_OF; import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_APPEND_BOOLEAN; import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_APPEND_CHAR; import static org.elasticsearch.painless.WriterConstants.STRINGBUILDER_APPEND_DOUBLE; @@ -175,11 +159,11 @@ public final class MethodWriter extends GeneratorAdapter { writeCast(from, to); unbox(to.type); } else if (cast.boxFrom) { - box(from.type); + valueOf(from.type); writeCast(from, to); } else if (cast.boxTo) { writeCast(from, to); - box(to.type); + valueOf(to.type); } else { writeCast(from, to); } @@ -200,26 +184,6 @@ public final class MethodWriter extends GeneratorAdapter { } } - /** - * ASM does boxing in an evil way to be compatible with Java prior to verison 5. - * Supporting versions prior to 5 is not a requirement of this project, so the modern - * boxing methods are used instead. - */ - @Override - public void box(final org.objectweb.asm.Type type) { - switch (type.getSort()) { - case org.objectweb.asm.Type.VOID: visitInsn(Opcodes.ACONST_NULL); break; - case org.objectweb.asm.Type.BOOLEAN: invokeStatic(BOOLEAN_OBJECT , BOOLEAN_VALUE_OF); break; - case org.objectweb.asm.Type.BYTE: invokeStatic(BYTE_OBJECT , BYTE_VALUE_OF); break; - case org.objectweb.asm.Type.SHORT: invokeStatic(SHORT_OBJECT , SHORT_VALUE_OF); break; - case org.objectweb.asm.Type.CHAR: invokeStatic(CHARACTER_OBJECT, CHARACTER_VALUE_OF); break; - case org.objectweb.asm.Type.INT: invokeStatic(INTEGER_OBJECT , INTEGER_VALUE_OF); break; - case org.objectweb.asm.Type.LONG: invokeStatic(LONG_OBJECT , LONG_VALUE_OF); break; - case org.objectweb.asm.Type.FLOAT: invokeStatic(FLOAT_OBJECT , FLOAT_VALUE_OF); break; - case org.objectweb.asm.Type.DOUBLE: invokeStatic(DOUBLE_OBJECT , DOUBLE_VALUE_OF); break; - } - } - public void writeBranch(final Label tru, final Label fals) { if (tru != null) { visitJumpInsn(Opcodes.IFNE, tru); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java index c9d24212bbc..47927438804 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java @@ -147,16 +147,6 @@ public final class WriterConstants { public final static Type FLOAT_OBJECT = Type.getType(Float.class); public final static Type DOUBLE_OBJECT = Type.getType(Double.class); - /** box methods to replace the GeneratorAdapter's slow way of boxing */ - public final static Method BOOLEAN_VALUE_OF = getAsmMethod(Boolean.class , "valueOf", boolean.class); - public final static Method BYTE_VALUE_OF = getAsmMethod(Byte.class , "valueOf", byte.class); - public final static Method SHORT_VALUE_OF = getAsmMethod(Short.class , "valueOf", short.class); - public final static Method CHARACTER_VALUE_OF = getAsmMethod(Character.class, "valueOf", char.class); - public final static Method INTEGER_VALUE_OF = getAsmMethod(Integer.class , "valueOf", int.class); - public final static Method LONG_VALUE_OF = getAsmMethod(Long.class , "valueOf", long.class); - public final static Method FLOAT_VALUE_OF = getAsmMethod(Float.class , "valueOf", float.class); - public final static Method DOUBLE_VALUE_OF = getAsmMethod(Double.class , "valueOf", double.class); - private static Method getAsmMethod(final Class rtype, final String name, final Class... ptypes) { return new Method(name, MethodType.methodType(rtype, ptypes).toMethodDescriptorString()); } From b156438957f22183b8c0ae3b45204af599c91e3f Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Fri, 20 May 2016 11:22:18 -0700 Subject: [PATCH 22/22] Proxy box method to use valueOf. --- .../org/elasticsearch/painless/MethodWriter.java | 12 ++++++++++-- .../org/elasticsearch/painless/WriterConstants.java | 12 +----------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java index f0477478fda..90c02b7e801 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/MethodWriter.java @@ -159,11 +159,11 @@ public final class MethodWriter extends GeneratorAdapter { writeCast(from, to); unbox(to.type); } else if (cast.boxFrom) { - valueOf(from.type); + box(from.type); writeCast(from, to); } else if (cast.boxTo) { writeCast(from, to); - valueOf(to.type); + box(to.type); } else { writeCast(from, to); } @@ -184,6 +184,14 @@ public final class MethodWriter extends GeneratorAdapter { } } + /** + * Proxy the box method to use valueOf instead to ensure that the modern boxing methods are used. + */ + @Override + public void box(org.objectweb.asm.Type type) { + valueOf(type); + } + public void writeBranch(final Label tru, final Label fals) { if (tru != null) { visitJumpInsn(Opcodes.IFNE, tru); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java index 47927438804..410c06e6fd7 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/WriterConstants.java @@ -135,17 +135,7 @@ public final class WriterConstants { public final static Method STRINGBUILDER_APPEND_OBJECT = getAsmMethod(StringBuilder.class, "append", Object.class); public final static Method STRINGBUILDER_TOSTRING = getAsmMethod(String.class, "toString"); - public final static Method CHECKEQUALS = - getAsmMethod(boolean.class, "checkEquals", Object.class, Object.class); - - public final static Type BOOLEAN_OBJECT = Type.getType(Boolean.class); - public final static Type BYTE_OBJECT = Type.getType(Byte.class); - public final static Type SHORT_OBJECT = Type.getType(Short.class); - public final static Type CHARACTER_OBJECT = Type.getType(Character.class); - public final static Type INTEGER_OBJECT = Type.getType(Integer.class); - public final static Type LONG_OBJECT = Type.getType(Long.class); - public final static Type FLOAT_OBJECT = Type.getType(Float.class); - public final static Type DOUBLE_OBJECT = Type.getType(Double.class); + public final static Method CHECKEQUALS = getAsmMethod(boolean.class, "checkEquals", Object.class, Object.class); private static Method getAsmMethod(final Class rtype, final String name, final Class... ptypes) { return new Method(name, MethodType.methodType(rtype, ptypes).toMethodDescriptorString());