From e72f35073c3e9a4d8d95b87a36668f0e9cc03381 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Wed, 18 Jul 2018 13:12:40 -0700 Subject: [PATCH 1/4] Simplify naming scheme. --- .../painless/AnalyzerCaster.java | 4 +- .../java/org/elasticsearch/painless/Def.java | 6 +- .../elasticsearch/painless/FunctionRef.java | 2 +- .../org/elasticsearch/painless/Locals.java | 2 +- .../painless/ScriptClassInfo.java | 2 +- .../lookup/PainlessLookupBuilder.java | 227 ++++++------- .../lookup/PainlessLookupUtility.java | 321 +++++++++--------- .../painless/lookup/PainlessMethod.java | 14 +- .../painless/node/AExpression.java | 2 +- .../elasticsearch/painless/node/EBinary.java | 44 +-- .../painless/node/ECapturingFunctionRef.java | 8 +- .../elasticsearch/painless/node/ECast.java | 2 +- .../elasticsearch/painless/node/EComp.java | 32 +- .../painless/node/EFunctionRef.java | 4 +- .../painless/node/EInstanceof.java | 6 +- .../elasticsearch/painless/node/ELambda.java | 10 +- .../elasticsearch/painless/node/ENull.java | 2 +- .../elasticsearch/painless/node/EUnary.java | 6 +- .../elasticsearch/painless/node/PBrace.java | 2 +- .../painless/node/PCallInvoke.java | 2 +- .../elasticsearch/painless/node/PField.java | 7 +- .../painless/node/PSubField.java | 2 +- .../elasticsearch/painless/node/SEach.java | 2 +- .../painless/node/SFunction.java | 4 +- .../painless/node/SSubEachArray.java | 2 +- .../painless/node/SSubEachIterable.java | 4 +- .../painless/PainlessDocGenerator.java | 4 +- 27 files changed, 353 insertions(+), 370 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 6cfc7ff6ebfd2..ddcae5abb6991 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 @@ -466,8 +466,8 @@ public static PainlessCast getLegalCast(Location location, Class actual, Clas return PainlessCast.standard(actual, expected, explicit); } else { throw location.createError(new ClassCastException("Cannot cast from " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(actual) + "] to " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(actual) + "] to " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expected) + "].")); } } 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 f3388fc4bb268..27f64e2a0d7d2 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 @@ -302,7 +302,7 @@ static MethodHandle lookupMethod(PainlessLookup painlessLookup, MethodHandles.Lo nestedType, 0, DefBootstrap.REFERENCE, - PainlessLookupUtility.anyTypeToPainlessTypeName(interfaceType)); + PainlessLookupUtility.painlessTypeToPainlessTypeName(interfaceType)); filter = nested.dynamicInvoker(); } else { throw new AssertionError(); @@ -334,7 +334,7 @@ static MethodHandle lookupReference(PainlessLookup painlessLookup, MethodHandles int arity = interfaceMethod.arguments.size(); PainlessMethod implMethod = lookupMethodInternal(painlessLookup, receiverClass, name, arity); return lookupReferenceInternal(painlessLookup, methodHandlesLookup, interfaceType, - PainlessLookupUtility.anyTypeToPainlessTypeName(implMethod.target), implMethod.name, receiverClass); + PainlessLookupUtility.painlessTypeToPainlessTypeName(implMethod.target), implMethod.name, receiverClass); } /** Returns a method handle to an implementation of clazz, given method reference signature. */ @@ -347,7 +347,7 @@ private static MethodHandle lookupReferenceInternal(PainlessLookup painlessLooku PainlessMethod interfaceMethod = painlessLookup.getPainlessStructFromJavaClass(clazz).functionalMethod; if (interfaceMethod == null) { throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " + - "to [" + PainlessLookupUtility.anyTypeToPainlessTypeName(clazz) + "], not a functional interface"); + "to [" + PainlessLookupUtility.painlessTypeToPainlessTypeName(clazz) + "], not a functional interface"); } int arity = interfaceMethod.arguments.size() + captures.length; final MethodHandle handle; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/FunctionRef.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/FunctionRef.java index d64e833912f59..bf574ee0f4c1f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/FunctionRef.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/FunctionRef.java @@ -168,7 +168,7 @@ private static PainlessMethod lookup(PainlessLookup painlessLookup, Class exp PainlessMethod method = painlessLookup.getPainlessStructFromJavaClass(expected).functionalMethod; if (method == null) { throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " + - "to [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "], not a functional interface"); + "to [" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expected) + "], not a functional interface"); } // lookup requested method diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Locals.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Locals.java index 6c1010a34505a..d977774ef7bc3 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Locals.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Locals.java @@ -292,7 +292,7 @@ public int getSlot() { @Override public String toString() { StringBuilder b = new StringBuilder(); - b.append("Variable[type=").append(PainlessLookupUtility.anyTypeToPainlessTypeName(clazz)); + b.append("Variable[type=").append(PainlessLookupUtility.painlessTypeToPainlessTypeName(clazz)); b.append(",name=").append(name); b.append(",slot=").append(slot); if (readonly) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java index ff2061a9a4b92..df13d22cc690b 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java @@ -183,7 +183,7 @@ private MethodArgument methodArgument(PainlessLookup painlessLookup, Class cl private static Class definitionTypeForClass(PainlessLookup painlessLookup, Class type, Function, String> unknownErrorMessageSource) { - type = PainlessLookupUtility.javaObjectTypeToPainlessDefType(type); + type = PainlessLookupUtility.ObjectTypeTodefType(type); Class componentType = type; while (componentType.isArray()) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupBuilder.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupBuilder.java index ecf15c7ad2cd0..d2a6dc42f15b1 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupBuilder.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupBuilder.java @@ -30,7 +30,6 @@ import java.lang.invoke.MethodHandles; import java.lang.reflect.Modifier; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -39,20 +38,20 @@ import java.util.Stack; import java.util.regex.Pattern; -import static org.elasticsearch.painless.lookup.PainlessLookupUtility.DEF_PAINLESS_CLASS_NAME; -import static org.elasticsearch.painless.lookup.PainlessLookupUtility.anyTypeNameToPainlessTypeName; +import static org.elasticsearch.painless.lookup.PainlessLookupUtility.DEF_PAINLESS_TYPE_NAME; import static org.elasticsearch.painless.lookup.PainlessLookupUtility.buildPainlessMethodKey; +import static org.elasticsearch.painless.lookup.PainlessLookupUtility.javaTypeNameToPainlessTypeName; public class PainlessLookupBuilder { private static class PainlessMethodCacheKey { - private final Class javaClass; + private final Class painlessType; private final String methodName; private final List> painlessTypeParameters; - private PainlessMethodCacheKey(Class javaClass, String methodName, List> painlessTypeParameters) { - this.javaClass = javaClass; + private PainlessMethodCacheKey(Class painlessType, String methodName, List> painlessTypeParameters) { + this.painlessType = painlessType; this.methodName = methodName; this.painlessTypeParameters = Collections.unmodifiableList(painlessTypeParameters); } @@ -69,27 +68,27 @@ public boolean equals(Object object) { PainlessMethodCacheKey that = (PainlessMethodCacheKey)object; - return Objects.equals(javaClass, that.javaClass) && - Objects.equals(methodName, that.methodName) && + return Objects.equals(painlessType, that.painlessType) && + Objects.equals(methodName, that.methodName) && Objects.equals(painlessTypeParameters, that.painlessTypeParameters); } @Override public int hashCode() { - return Objects.hash(javaClass, methodName, painlessTypeParameters); + return Objects.hash(painlessType, methodName, painlessTypeParameters); } } private static class PainlessFieldCacheKey { - private final Class javaClass; - private final String fieldName; private final Class painlessType; + private final String fieldName; + private final Class painlessTypeParameter; - private PainlessFieldCacheKey(Class javaClass, String fieldName, Class painlessType) { - this.javaClass = javaClass; - this.fieldName = fieldName; + private PainlessFieldCacheKey(Class painlessType, String fieldName, Class painlessTypeParameter) { this.painlessType = painlessType; + this.fieldName = fieldName; + this.painlessTypeParameter = painlessTypeParameter; } @Override @@ -104,14 +103,14 @@ public boolean equals(Object object) { PainlessFieldCacheKey that = (PainlessFieldCacheKey) object; - return Objects.equals(javaClass, that.javaClass) && - Objects.equals(fieldName, that.fieldName) && - Objects.equals(painlessType, that.painlessType); + return Objects.equals(painlessType, that.painlessType) && + Objects.equals(fieldName, that.fieldName) && + Objects.equals(painlessTypeParameter, that.painlessTypeParameter); } @Override public int hashCode() { - return Objects.hash(javaClass, fieldName, painlessType); + return Objects.hash(painlessType, fieldName, painlessTypeParameter); } } @@ -122,157 +121,131 @@ public int hashCode() { private static final Pattern METHOD_NAME_PATTERN = Pattern.compile("^[_a-zA-Z][_a-zA-Z0-9]*$"); private static final Pattern FIELD_NAME_PATTERN = Pattern.compile("^[_a-zA-Z][_a-zA-Z0-9]*$"); - private static String anyTypesArrayToCanonicalString(Class[] anyTypesArray, boolean toPainlessTypes) { - return anyTypesListToCanonicalString(Arrays.asList(anyTypesArray), toPainlessTypes); - } - - private static String anyTypesListToCanonicalString(List> anyTypesList, boolean toPainlessTypes) { - StringBuilder anyTypesCanonicalStringBuilder = new StringBuilder("["); - - int anyTypesSize = anyTypesList.size(); - int anyTypesIndex = 0; - - for (Class anyType : anyTypesList) { - String anyTypeCanonicalName = anyType.getCanonicalName(); - - if (toPainlessTypes) { - anyTypeCanonicalName = anyTypeNameToPainlessTypeName(anyTypeCanonicalName); - } - - anyTypesCanonicalStringBuilder.append(anyTypeCanonicalName); - - if (++anyTypesIndex < anyTypesSize) { - anyTypesCanonicalStringBuilder.append(","); - } - } - - anyTypesCanonicalStringBuilder.append("]"); - - return anyTypesCanonicalStringBuilder.toString(); - } - private final List whitelists; - private final Map> painlessClassNamesToJavaClasses; - private final Map, PainlessClassBuilder> javaClassesToPainlessClassBuilders; + private final Map> painlessTypeNamesToPainlessTypes; + private final Map, PainlessClassBuilder> painlessTypesToPainlessClasses; public PainlessLookupBuilder(List whitelists) { this.whitelists = whitelists; - painlessClassNamesToJavaClasses = new HashMap<>(); - javaClassesToPainlessClassBuilders = new HashMap<>(); + painlessTypeNamesToPainlessTypes = new HashMap<>(); + painlessTypesToPainlessClasses = new HashMap<>(); - painlessClassNamesToJavaClasses.put(DEF_PAINLESS_CLASS_NAME, def.class); - javaClassesToPainlessClassBuilders.put(def.class, - new PainlessClassBuilder(DEF_PAINLESS_CLASS_NAME, Object.class, Type.getType(Object.class))); + painlessTypeNamesToPainlessTypes.put(DEF_PAINLESS_TYPE_NAME, def.class); + painlessTypesToPainlessClasses.put(def.class, + new PainlessClassBuilder(DEF_PAINLESS_TYPE_NAME, Object.class, Type.getType(Object.class))); } private Class painlessTypeNameToPainlessType(String painlessTypeName) { - return PainlessLookupUtility.painlessTypeNameToPainlessType(painlessTypeName, painlessClassNamesToJavaClasses); + return PainlessLookupUtility.painlessTypeNameToPainlessType(painlessTypeName, painlessTypeNamesToPainlessTypes); } private void validatePainlessType(Class painlessType) { - PainlessLookupUtility.validatePainlessType(painlessType, javaClassesToPainlessClassBuilders.keySet()); + PainlessLookupUtility.validatePainlessType(painlessType, painlessTypesToPainlessClasses.keySet()); } - public void addPainlessClass(ClassLoader classLoader, String javaClassName, boolean importPainlessClassName) { + public void addPainlessClass(ClassLoader classLoader, String javaTypeName, boolean importPainlessTypeName) { Objects.requireNonNull(classLoader); - Objects.requireNonNull(javaClassName); + Objects.requireNonNull(javaTypeName); - String painlessClassName = anyTypeNameToPainlessTypeName(javaClassName); + String painlessTypeName = javaTypeNameToPainlessTypeName(javaTypeName); - if (CLASS_NAME_PATTERN.matcher(painlessClassName).matches() == false) { - throw new IllegalArgumentException("invalid painless class name [" + painlessClassName + "]"); + if (CLASS_NAME_PATTERN.matcher(painlessTypeName).matches() == false) { + throw new IllegalArgumentException("invalid painless type name [" + painlessTypeName + "]"); } - String importedPainlessClassName = anyTypeNameToPainlessTypeName(javaClassName.substring(javaClassName.lastIndexOf('.') + 1)); + String importedPainlessTypeName = javaTypeNameToPainlessTypeName(javaTypeName.substring(javaTypeName.lastIndexOf('.') + 1)); - Class javaClass; + Class painlessType; - if ("void".equals(javaClassName)) javaClass = void.class; - else if ("boolean".equals(javaClassName)) javaClass = boolean.class; - else if ("byte".equals(javaClassName)) javaClass = byte.class; - else if ("short".equals(javaClassName)) javaClass = short.class; - else if ("char".equals(javaClassName)) javaClass = char.class; - else if ("int".equals(javaClassName)) javaClass = int.class; - else if ("long".equals(javaClassName)) javaClass = long.class; - else if ("float".equals(javaClassName)) javaClass = float.class; - else if ("double".equals(javaClassName)) javaClass = double.class; + if ("void".equals(javaTypeName)) painlessType = void.class; + else if ("boolean".equals(javaTypeName)) painlessType = boolean.class; + else if ("byte".equals(javaTypeName)) painlessType = byte.class; + else if ("short".equals(javaTypeName)) painlessType = short.class; + else if ("char".equals(javaTypeName)) painlessType = char.class; + else if ("int".equals(javaTypeName)) painlessType = int.class; + else if ("long".equals(javaTypeName)) painlessType = long.class; + else if ("float".equals(javaTypeName)) painlessType = float.class; + else if ("double".equals(javaTypeName)) painlessType = double.class; else { try { - javaClass = Class.forName(javaClassName, true, classLoader); - - if (javaClass == def.class) { - throw new IllegalArgumentException("cannot add reserved painless class [" + DEF_PAINLESS_CLASS_NAME + "]"); - } + painlessType = Class.forName(javaTypeName, true, classLoader); - if (javaClass.isArray()) { - throw new IllegalArgumentException("cannot add an array type java class [" + javaClassName + "] as a painless class"); + if (painlessType == def.class) { + throw new IllegalArgumentException("cannot add reserved painless type [" + DEF_PAINLESS_TYPE_NAME + "]"); } } catch (ClassNotFoundException cnfe) { - throw new IllegalArgumentException("java class [" + javaClassName + "] not found", cnfe); + throw new IllegalArgumentException("java type [" + javaTypeName + "] not found", cnfe); } } - addPainlessClass(painlessClassName, importedPainlessClassName, javaClass, importPainlessClassName); + addPainlessClass(painlessTypeName, importedPainlessTypeName, painlessType, importPainlessTypeName); } - public void addPainlessClass(Class javaClass, boolean importPainlessClassName) { - Objects.requireNonNull(javaClass); + public void addPainlessClass(Class painlessType, boolean importPainlessTypeName) { + Objects.requireNonNull(painlessType); + + if (painlessType == def.class) { + throw new IllegalArgumentException("cannot add reserved painless type [" + DEF_PAINLESS_TYPE_NAME + "]"); + } + + String javaTypeName = painlessType.getCanonicalName(); + String painlessTypeName = javaTypeNameToPainlessTypeName(javaTypeName); - if (javaClass == def.class) { - throw new IllegalArgumentException("cannot specify reserved painless class [" + DEF_PAINLESS_CLASS_NAME + "]"); + if (painlessType.isArray()) { + throw new IllegalArgumentException("invalid painless type name [" + painlessTypeName + "]"); } - String javaClassName = javaClass.getCanonicalName(); - String painlessClassName = anyTypeNameToPainlessTypeName(javaClassName); - String importedPainlessClassName = anyTypeNameToPainlessTypeName(javaClassName.substring(javaClassName.lastIndexOf('.') + 1)); + String importedPainlessTypeName = javaTypeNameToPainlessTypeName(javaTypeName.substring(javaTypeName.lastIndexOf('.') + 1)); - addPainlessClass(painlessClassName, importedPainlessClassName, javaClass, importPainlessClassName); + addPainlessClass(painlessTypeName, importedPainlessTypeName, painlessType, importPainlessTypeName); } private void addPainlessClass( - String painlessClassName, String importedPainlessClassName, Class javaClass, boolean importPainlessClassName) { - PainlessClassBuilder existingPainlessClassBuilder = javaClassesToPainlessClassBuilders.get(javaClass); + String painlessTypeName, String importedPainlessTypeName, Class painlessType, boolean importPainlessClassName) { + + PainlessClassBuilder existingPainlessClassBuilder = painlessTypesToPainlessClasses.get(painlessType); if (existingPainlessClassBuilder == null) { - PainlessClassBuilder painlessClassBuilder = new PainlessClassBuilder(painlessClassName, javaClass, Type.getType(javaClass)); - painlessClassNamesToJavaClasses.put(painlessClassName, javaClass); - javaClassesToPainlessClassBuilders.put(javaClass, painlessClassBuilder); - } else if (existingPainlessClassBuilder.clazz.equals(javaClass) == false) { - throw new IllegalArgumentException("painless class [" + painlessClassName + "] illegally represents multiple java classes " + - "[" + javaClass.getCanonicalName() + "] and [" + existingPainlessClassBuilder.clazz.getCanonicalName() + "]"); + PainlessClassBuilder painlessClassBuilder = + new PainlessClassBuilder(painlessTypeName, painlessType, Type.getType(painlessType)); + + painlessTypeNamesToPainlessTypes.put(painlessTypeName, painlessType); + painlessTypesToPainlessClasses.put(painlessType, painlessClassBuilder); + } else if (existingPainlessClassBuilder.clazz.equals(painlessType) == false) { + throw new IllegalArgumentException("painless type [" + painlessTypeName + "] illegally represents multiple java types " + + "[" + painlessType.getCanonicalName() + "] and [" + existingPainlessClassBuilder.clazz.getCanonicalName() + "]"); } - if (painlessClassName.equals(importedPainlessClassName)) { + if (painlessTypeName.equals(importedPainlessTypeName)) { if (importPainlessClassName == true) { throw new IllegalArgumentException( - "must use only_fqn parameter on painless class [" + painlessClassName + "] with no package"); + "must use only_fqn parameter on painless type [" + painlessTypeName + "] with no package"); } } else { - Class importedJavaClass = painlessClassNamesToJavaClasses.get(importedPainlessClassName); + Class importedPainlessType = painlessTypeNamesToPainlessTypes.get(importedPainlessTypeName); - if (importedJavaClass == null) { + if (importedPainlessType == null) { if (importPainlessClassName) { if (existingPainlessClassBuilder != null) { throw new IllegalArgumentException( - "inconsistent only_fqn parameters found for painless class [" + painlessClassName + "]"); + "inconsistent only_fqn parameters found for painless type [" + painlessTypeName + "]"); } - painlessClassNamesToJavaClasses.put(importedPainlessClassName, javaClass); + painlessTypeNamesToPainlessTypes.put(importedPainlessTypeName, painlessType); } - } else if (importedJavaClass.equals(javaClass) == false) { - throw new IllegalArgumentException("painless class [" + importedPainlessClassName + "] illegally represents multiple " + - "java classes [" + javaClass.getCanonicalName() + "] and [" + importedJavaClass.getCanonicalName() + "]"); + } else if (importedPainlessType.equals(painlessType) == false) { + throw new IllegalArgumentException("painless type [" + importedPainlessTypeName + "] illegally represents multiple " + + "java types [" + painlessType.getCanonicalName() + "] and [" + importedPainlessType.getCanonicalName() + "]"); } else if (importPainlessClassName == false) { - throw new IllegalArgumentException( - "inconsistent only_fqn parameters found for painless class [" + painlessClassName + "]"); + throw new IllegalArgumentException("inconsistent only_fqn parameters found for painless type [" + painlessTypeName + "]"); } } } private void addConstructor(String ownerStructName, WhitelistConstructor whitelistConstructor) { - PainlessClassBuilder ownerStruct = javaClassesToPainlessClassBuilders.get(painlessClassNamesToJavaClasses.get(ownerStructName)); + PainlessClassBuilder ownerStruct = painlessTypesToPainlessClasses.get(painlessTypeNamesToPainlessTypes.get(ownerStructName)); if (ownerStruct == null) { throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for constructor with " + @@ -289,7 +262,7 @@ private void addConstructor(String ownerStructName, WhitelistConstructor whiteli Class painlessParameterClass = painlessTypeNameToPainlessType(painlessParameterTypeName); painlessParametersTypes.add(painlessParameterClass); - javaClassParameters[parameterCount] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(painlessParameterClass); + javaClassParameters[parameterCount] = PainlessLookupUtility.defTypeToObjectType(painlessParameterClass); } catch (IllegalArgumentException iae) { throw new IllegalArgumentException("struct not defined for constructor parameter [" + painlessParameterTypeName + "] " + "with owner struct [" + ownerStructName + "] and constructor parameters " + @@ -333,7 +306,7 @@ private void addConstructor(String ownerStructName, WhitelistConstructor whiteli } private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName, WhitelistMethod whitelistMethod) { - PainlessClassBuilder ownerStruct = javaClassesToPainlessClassBuilders.get(painlessClassNamesToJavaClasses.get(ownerStructName)); + PainlessClassBuilder ownerStruct = painlessTypesToPainlessClasses.get(painlessTypeNamesToPainlessTypes.get(ownerStructName)); if (ownerStruct == null) { throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for method with " + @@ -376,7 +349,7 @@ private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName, painlessParametersTypes.add(painlessParameterClass); javaClassParameters[parameterCount + augmentedOffset] = - PainlessLookupUtility.painlessDefTypeToJavaObjectType(painlessParameterClass); + PainlessLookupUtility.defTypeToObjectType(painlessParameterClass); } catch (IllegalArgumentException iae) { throw new IllegalArgumentException("struct not defined for method parameter [" + painlessParameterTypeName + "] " + "with owner struct [" + ownerStructName + "] and method with name [" + whitelistMethod.javaMethodName + "] " + @@ -405,7 +378,7 @@ private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName, "and parameters " + whitelistMethod.painlessParameterTypeNames, iae); } - if (javaMethod.getReturnType() != PainlessLookupUtility.painlessDefTypeToJavaObjectType(painlessReturnClass)) { + if (javaMethod.getReturnType() != PainlessLookupUtility.defTypeToObjectType(painlessReturnClass)) { throw new IllegalArgumentException("specified return type class [" + painlessReturnClass + "] " + "does not match the return type class [" + javaMethod.getReturnType() + "] for the " + "method with name [" + whitelistMethod.javaMethodName + "] " + @@ -471,7 +444,7 @@ private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName, } private void addField(String ownerStructName, WhitelistField whitelistField) { - PainlessClassBuilder ownerStruct = javaClassesToPainlessClassBuilders.get(painlessClassNamesToJavaClasses.get(ownerStructName)); + PainlessClassBuilder ownerStruct = painlessTypesToPainlessClasses.get(painlessTypeNamesToPainlessTypes.get(ownerStructName)); if (ownerStruct == null) { throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for method with " + @@ -552,7 +525,7 @@ private void addField(String ownerStructName, WhitelistField whitelistField) { } private void copyStruct(String struct, List children) { - final PainlessClassBuilder owner = javaClassesToPainlessClassBuilders.get(painlessClassNamesToJavaClasses.get(struct)); + final PainlessClassBuilder owner = painlessTypesToPainlessClasses.get(painlessTypeNamesToPainlessTypes.get(struct)); if (owner == null) { throw new IllegalArgumentException("Owner struct [" + struct + "] not defined for copy."); @@ -560,7 +533,7 @@ private void copyStruct(String struct, List children) { for (int count = 0; count < children.size(); ++count) { final PainlessClassBuilder child = - javaClassesToPainlessClassBuilders.get(painlessClassNamesToJavaClasses.get(children.get(count))); + painlessTypesToPainlessClasses.get(painlessTypeNamesToPainlessTypes.get(children.get(count))); if (child == null) { throw new IllegalArgumentException("Child struct [" + children.get(count) + "]" + @@ -734,7 +707,7 @@ public PainlessLookup build() { for (WhitelistClass whitelistStruct : whitelist.whitelistStructs) { String painlessTypeName = whitelistStruct.javaClassName.replace('$', '.'); PainlessClassBuilder painlessStruct = - javaClassesToPainlessClassBuilders.get(painlessClassNamesToJavaClasses.get(painlessTypeName)); + painlessTypesToPainlessClasses.get(painlessTypeNamesToPainlessTypes.get(painlessTypeName)); if (painlessStruct != null && painlessStruct.clazz.getName().equals(whitelistStruct.javaClassName) == false) { throw new IllegalArgumentException("struct [" + painlessStruct.name + "] cannot represent multiple classes " + @@ -745,8 +718,8 @@ public PainlessLookup build() { addPainlessClass( whitelist.javaClassLoader, whitelistStruct.javaClassName, whitelistStruct.onlyFQNJavaClassName == false); - painlessStruct = javaClassesToPainlessClassBuilders.get(painlessClassNamesToJavaClasses.get(painlessTypeName)); - javaClassesToPainlessClassBuilders.put(painlessStruct.clazz, painlessStruct); + painlessStruct = painlessTypesToPainlessClasses.get(painlessTypeNamesToPainlessTypes.get(painlessTypeName)); + painlessTypesToPainlessClasses.put(painlessStruct.clazz, painlessStruct); } } @@ -779,8 +752,8 @@ public PainlessLookup build() { // goes through each Painless struct and determines the inheritance list, // and then adds all inherited types to the Painless struct's whitelist - for (Class javaClass : javaClassesToPainlessClassBuilders.keySet()) { - PainlessClassBuilder painlessStruct = javaClassesToPainlessClassBuilders.get(javaClass); + for (Class javaClass : painlessTypesToPainlessClasses.keySet()) { + PainlessClassBuilder painlessStruct = painlessTypesToPainlessClasses.get(javaClass); List painlessSuperStructs = new ArrayList<>(); Class javaSuperClass = painlessStruct.clazz.getSuperclass(); @@ -791,7 +764,7 @@ public PainlessLookup build() { // adds super classes to the inheritance list if (javaSuperClass != null && javaSuperClass.isInterface() == false) { while (javaSuperClass != null) { - PainlessClassBuilder painlessSuperStruct = javaClassesToPainlessClassBuilders.get(javaSuperClass); + PainlessClassBuilder painlessSuperStruct = painlessTypesToPainlessClasses.get(javaSuperClass); if (painlessSuperStruct != null) { painlessSuperStructs.add(painlessSuperStruct.name); @@ -807,7 +780,7 @@ public PainlessLookup build() { Class javaInterfaceLookup = javaInteraceLookups.pop(); for (Class javaSuperInterface : javaInterfaceLookup.getInterfaces()) { - PainlessClassBuilder painlessInterfaceStruct = javaClassesToPainlessClassBuilders.get(javaSuperInterface); + PainlessClassBuilder painlessInterfaceStruct = painlessTypesToPainlessClasses.get(javaSuperInterface); if (painlessInterfaceStruct != null) { String painlessInterfaceStructName = painlessInterfaceStruct.name; @@ -828,7 +801,7 @@ public PainlessLookup build() { // copies methods and fields from Object into interface types if (painlessStruct.clazz.isInterface() || (def.class.getSimpleName()).equals(painlessStruct.name)) { - PainlessClassBuilder painlessObjectStruct = javaClassesToPainlessClassBuilders.get(Object.class); + PainlessClassBuilder painlessObjectStruct = painlessTypesToPainlessClasses.get(Object.class); if (painlessObjectStruct != null) { copyStruct(painlessStruct.name, Collections.singletonList(painlessObjectStruct.name)); @@ -837,18 +810,18 @@ public PainlessLookup build() { } // precompute runtime classes - for (PainlessClassBuilder painlessStruct : javaClassesToPainlessClassBuilders.values()) { + for (PainlessClassBuilder painlessStruct : painlessTypesToPainlessClasses.values()) { addRuntimeClass(painlessStruct); } Map, PainlessClass> javaClassesToPainlessClasses = new HashMap<>(); // copy all structs to make them unmodifiable for outside users: - for (Map.Entry,PainlessClassBuilder> entry : javaClassesToPainlessClassBuilders.entrySet()) { + for (Map.Entry,PainlessClassBuilder> entry : painlessTypesToPainlessClasses.entrySet()) { entry.getValue().functionalMethod = computeFunctionalInterfaceMethod(entry.getValue()); javaClassesToPainlessClasses.put(entry.getKey(), entry.getValue().build()); } - return new PainlessLookup(painlessClassNamesToJavaClasses, javaClassesToPainlessClasses); + return new PainlessLookup(painlessTypeNamesToPainlessTypes, javaClassesToPainlessClasses); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java index 0f7c8fb915cdf..1fc87c83c479e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java @@ -19,131 +19,51 @@ package org.elasticsearch.painless.lookup; -import org.objectweb.asm.Type; - import java.util.Arrays; import java.util.Collection; +import java.util.List; import java.util.Map; +import java.util.Objects; /** - * This class contains methods shared by {@link PainlessLookupBuilder}, {@link PainlessLookup}, and other classes within - * Painless for conversion between type names and types along with some other various utility methods. + * This class contains methods shared by {@link PainlessLookupBuilder}, {@link PainlessLookup}, and other + * classes within Painless for conversion between type names and types along with some other various utility + * methods. * * The following terminology is used for variable names throughout the lookup package: * - * - javaClass (Class) - a java class including def and excluding array type java classes - * - javaClassName (String) - the fully qualified java class name for a javaClass - * - painlessClassName (String) - the fully qualified painless name or imported painless name for a painlessClass - * - anyClassName (String) - either a javaClassName or a painlessClassName - * - javaType (Class) - a java class excluding def and array type java classes - * - painlessType (Class) - a java class including def and array type java classes - * - javaTypeName (String) - the fully qualified java Type name for a javaType - * - painlessTypeName (String) - the fully qualified painless name or imported painless name for a painlessType - * - anyTypeName (String) - either a javaTypeName or a painlessTypeName + * - javaTypeName (String) - the fully qualified java type name for a painless type + * where '$' tokens are used to represent inner classes + * - painlessTypeName (String) - the fully qualified painless type name or imported painless + * type name for a painless type where '.' tokens replace '$' tokens + * - painlessType (Class) - a painless type represented by a java class including def + * and including array type java classes * - painlessClass (PainlessClass) - a painless class object * * Under ambiguous circumstances most variable names are prefixed with asm, java, or painless. - * If the variable name is the same for asm, java, and painless, no prefix is used. + * If the variable value is the same for asm, java, and painless, no prefix is used. */ public final class PainlessLookupUtility { - public static Class javaObjectTypeToPainlessDefType(Class javaType) { - if (javaType.isArray()) { - Class javaTypeComponent = javaType.getComponentType(); - int arrayDimensions = 1; - - while (javaTypeComponent.isArray()) { - javaTypeComponent = javaTypeComponent.getComponentType(); - ++arrayDimensions; - } - - if (javaTypeComponent == Object.class) { - char[] asmDescriptorBraces = new char[arrayDimensions]; - Arrays.fill(asmDescriptorBraces, '['); + public static String javaTypeNameToPainlessTypeName(String javaTypeName) { + Objects.requireNonNull(javaTypeName); + assert(javaTypeName.startsWith("[") == false); - String asmDescriptor = new String(asmDescriptorBraces) + Type.getType(def.class).getDescriptor(); - Type asmType = Type.getType(asmDescriptor); - - try { - return Class.forName(asmType.getInternalName().replace('/', '.')); - } catch (ClassNotFoundException cnfe) { - throw new IllegalStateException("internal error", cnfe); - } - } - } else if (javaType == Object.class) { - return def.class; + if (javaTypeName.startsWith(def.class.getName())) { + return javaTypeName.replace(def.class.getName(), DEF_PAINLESS_TYPE_NAME).replace('$', '.'); + } else { + return javaTypeName.replace('$', '.'); } - - return javaType; } - public static Class painlessDefTypeToJavaObjectType(Class painlessType) { - if (painlessType.isArray()) { - Class painlessTypeComponent = painlessType.getComponentType(); - int arrayDimensions = 1; - - while (painlessTypeComponent.isArray()) { - painlessTypeComponent = painlessTypeComponent.getComponentType(); - ++arrayDimensions; - } - - if (painlessTypeComponent == def.class) { - char[] asmDescriptorBraces = new char[arrayDimensions]; - Arrays.fill(asmDescriptorBraces, '['); + public static Class painlessTypeNameToPainlessType(String painlessTypeName, Map> painlessTypeNamesToPainlessTypes) { + Objects.requireNonNull(painlessTypeName); + Objects.requireNonNull(painlessTypeNamesToPainlessTypes); - String asmDescriptor = new String(asmDescriptorBraces) + Type.getType(Object.class).getDescriptor(); - Type asmType = Type.getType(asmDescriptor); + Class painlessType = painlessTypeNamesToPainlessTypes.get(painlessTypeName); - try { - return Class.forName(asmType.getInternalName().replace('/', '.')); - } catch (ClassNotFoundException exception) { - throw new IllegalStateException("internal error", exception); - } - } - } else if (painlessType == def.class) { - return Object.class; - } - - return painlessType; - } - - public static String anyTypeNameToPainlessTypeName(String anyTypeName) { - return anyTypeName.replace(def.class.getName(), DEF_PAINLESS_CLASS_NAME).replace('$', '.'); - } - - public static String anyTypeToPainlessTypeName(Class anyType) { - if (anyType.isLocalClass() || anyType.isAnonymousClass()) { - return null; - } else if (anyType.isArray()) { - Class anyTypeComponent = anyType.getComponentType(); - int arrayDimensions = 1; - - while (anyTypeComponent.isArray()) { - anyTypeComponent = anyTypeComponent.getComponentType(); - ++arrayDimensions; - } - - if (anyTypeComponent == def.class) { - StringBuilder painlessDefTypeNameArrayBuilder = new StringBuilder(DEF_PAINLESS_CLASS_NAME); - - for (int dimension = 0; dimension < arrayDimensions; dimension++) { - painlessDefTypeNameArrayBuilder.append("[]"); - } - - return painlessDefTypeNameArrayBuilder.toString(); - } - } else if (anyType == def.class) { - return DEF_PAINLESS_CLASS_NAME; - } - - return anyType.getCanonicalName().replace('$', '.'); - } - - public static Class painlessTypeNameToPainlessType(String painlessTypeName, Map> painlessClassNamesToJavaClasses) { - Class javaClass = painlessClassNamesToJavaClasses.get(painlessTypeName); - - if (javaClass != null) { - return javaClass; + if (painlessType != null) { + return painlessType; } int arrayDimensions = 0; @@ -163,30 +83,30 @@ public static Class painlessTypeNameToPainlessType(String painlessTypeName, M } painlessTypeName = painlessTypeName.substring(0, painlessTypeName.indexOf('[')); - javaClass = painlessClassNamesToJavaClasses.get(painlessTypeName); + painlessType = painlessTypeNamesToPainlessTypes.get(painlessTypeName); char javaDescriptorBraces[] = new char[arrayDimensions]; Arrays.fill(javaDescriptorBraces, '['); String javaDescriptor = new String(javaDescriptorBraces); - if (javaClass == boolean.class) { + if (painlessType == boolean.class) { javaDescriptor += "Z"; - } else if (javaClass == byte.class) { + } else if (painlessType == byte.class) { javaDescriptor += "B"; - } else if (javaClass == short.class) { + } else if (painlessType == short.class) { javaDescriptor += "S"; - } else if (javaClass == char.class) { + } else if (painlessType == char.class) { javaDescriptor += "C"; - } else if (javaClass == int.class) { + } else if (painlessType == int.class) { javaDescriptor += "I"; - } else if (javaClass == long.class) { + } else if (painlessType == long.class) { javaDescriptor += "J"; - } else if (javaClass == float.class) { + } else if (painlessType == float.class) { javaDescriptor += "F"; - } else if (javaClass == double.class) { + } else if (painlessType == double.class) { javaDescriptor += "D"; } else { - javaDescriptor += "L" + javaClass.getName() + ";"; + javaDescriptor += "L" + painlessType.getName() + ";"; } try { @@ -199,83 +119,172 @@ public static Class painlessTypeNameToPainlessType(String painlessTypeName, M throw new IllegalArgumentException("painless type [" + painlessTypeName + "] not found"); } - public static void validatePainlessType(Class painlessType, Collection> javaClasses) { - String painlessTypeName = anyTypeNameToPainlessTypeName(painlessType.getName()); + public static String painlessTypeToPainlessTypeName(Class painlessType) { + Objects.requireNonNull(painlessType); - while (painlessType.getComponentType() != null) { - painlessType = painlessType.getComponentType(); + if (painlessType.getCanonicalName().startsWith(def.class.getName())) { + return painlessType.getCanonicalName().replace(def.class.getName(), DEF_PAINLESS_TYPE_NAME).replace('$', '.'); + } else { + return painlessType.getCanonicalName().replace('$', '.'); } + } - if (javaClasses.contains(painlessType) == false) { - throw new IllegalArgumentException("painless type [" + painlessTypeName + "] not found"); + public static String painlessTypesToPainlessTypeNames(List> painlessTypes) { + StringBuilder painlessTypesStringBuilder = new StringBuilder("["); + + int anyTypesSize = painlessTypes.size(); + int anyTypesIndex = 0; + + for (Class painlessType : painlessTypes) { + String anyTypeCanonicalName = javaTypeNameToPainlessTypeName(painlessType.getCanonicalName()); + + painlessTypesStringBuilder.append(anyTypeCanonicalName); + + if (++anyTypesIndex < anyTypesSize) { + painlessTypesStringBuilder.append(","); + } } + + painlessTypesStringBuilder.append("]"); + + return painlessTypesStringBuilder.toString(); } - public static String buildPainlessMethodKey(String methodName, int methodArity) { - return methodName + "/" + methodArity; + public static Class ObjectTypeTodefType(Class painlessType) { + Objects.requireNonNull(painlessType); + + if (painlessType.isArray()) { + Class painlessTypeComponent = painlessType.getComponentType(); + int arrayDimensions = 1; + + while (painlessTypeComponent.isArray()) { + painlessTypeComponent = painlessTypeComponent.getComponentType(); + ++arrayDimensions; + } + + if (painlessTypeComponent == Object.class) { + char[] arrayBraces = new char[arrayDimensions]; + Arrays.fill(arrayBraces, '['); + + try { + return Class.forName(new String(arrayBraces) + def.class.getName() + ";"); + } catch (ClassNotFoundException cnfe) { + throw new IllegalStateException("internal error", cnfe); + } + } + } else if (painlessType == Object.class) { + return def.class; + } + + return painlessType; } - public static String buildPainlessFieldKey(String fieldName) { - return fieldName; + public static Class defTypeToObjectType(Class painlessType) { + Objects.requireNonNull(painlessType); + + if (painlessType.isArray()) { + Class painlessTypeComponent = painlessType.getComponentType(); + int arrayDimensions = 1; + + while (painlessTypeComponent.isArray()) { + painlessTypeComponent = painlessTypeComponent.getComponentType(); + ++arrayDimensions; + } + + if (painlessTypeComponent == def.class) { + char[] arrayBraces = new char[arrayDimensions]; + Arrays.fill(arrayBraces, '['); + + try { + return Class.forName(new String(arrayBraces) + Object.class.getName() + ";"); + } catch (ClassNotFoundException cnfe) { + throw new IllegalStateException("internal error", cnfe); + } + } + } else if (painlessType == def.class) { + return Object.class; + } + + return painlessType; } - public static Class getBoxedAnyType(Class anyType) { - if (anyType == boolean.class) { + public static void validatePainlessType(Class painlessType, Collection> painlessTypes) { + String painlessTypeName = javaTypeNameToPainlessTypeName(painlessType.getCanonicalName()); + + while (painlessType.getComponentType() != null) { + painlessType = painlessType.getComponentType(); + } + + if (painlessTypes.contains(painlessType) == false) { + throw new IllegalArgumentException("painless type [" + painlessTypeName + "] not found"); + } + } + + public static Class toBoxedPainlessType(Class painlessType) { + if (painlessType == boolean.class) { return Boolean.class; - } else if (anyType == byte.class) { + } else if (painlessType == byte.class) { return Byte.class; - } else if (anyType == short.class) { + } else if (painlessType == short.class) { return Short.class; - } else if (anyType == char.class) { + } else if (painlessType == char.class) { return Character.class; - } else if (anyType == int.class) { + } else if (painlessType == int.class) { return Integer.class; - } else if (anyType == long.class) { + } else if (painlessType == long.class) { return Long.class; - } else if (anyType == float.class) { + } else if (painlessType == float.class) { return Float.class; - } else if (anyType == double.class) { + } else if (painlessType == double.class) { return Double.class; } - return anyType; + return painlessType; } - public static Class getUnboxedAnyType(Class anyType) { - if (anyType == Boolean.class) { + public static Class toUnboxedPainlessType(Class painlessType) { + if (painlessType == Boolean.class) { return boolean.class; - } else if (anyType == Byte.class) { + } else if (painlessType == Byte.class) { return byte.class; - } else if (anyType == Short.class) { + } else if (painlessType == Short.class) { return short.class; - } else if (anyType == Character.class) { + } else if (painlessType == Character.class) { return char.class; - } else if (anyType == Integer.class) { + } else if (painlessType == Integer.class) { return int.class; - } else if (anyType == Long.class) { + } else if (painlessType == Long.class) { return long.class; - } else if (anyType == Float.class) { + } else if (painlessType == Float.class) { return float.class; - } else if (anyType == Double.class) { + } else if (painlessType == Double.class) { return double.class; } - return anyType; + return painlessType; } - public static boolean isAnyTypeConstant(Class anyType) { - return anyType == boolean.class || - anyType == byte.class || - anyType == short.class || - anyType == char.class || - anyType == int.class || - anyType == long.class || - anyType == float.class || - anyType == double.class || - anyType == String.class; + public static boolean isConstantPainlessType(Class painlessType) { + return painlessType == boolean.class || + painlessType == byte.class || + painlessType == short.class || + painlessType == char.class || + painlessType == int.class || + painlessType == long.class || + painlessType == float.class || + painlessType == double.class || + painlessType == String.class; + } + + public static String buildPainlessMethodKey(String methodName, int methodArity) { + return methodName + "/" + methodArity; + } + + public static String buildPainlessFieldKey(String fieldName) { + return fieldName; } - public static final String DEF_PAINLESS_CLASS_NAME = def.class.getSimpleName(); + public static final String DEF_PAINLESS_TYPE_NAME = "def"; public static final String CONSTRUCTOR_ANY_NAME = ""; private PainlessLookupUtility() { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessMethod.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessMethod.java index 2b0d44e71766d..fd63daf4eff2a 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessMethod.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessMethod.java @@ -70,21 +70,21 @@ public MethodType getMethodType() { params = new Class[1 + arguments.size()]; params[0] = augmentation; for (int i = 0; i < arguments.size(); i++) { - params[i + 1] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(arguments.get(i)); + params[i + 1] = PainlessLookupUtility.defTypeToObjectType(arguments.get(i)); } - returnValue = PainlessLookupUtility.painlessDefTypeToJavaObjectType(rtn); + returnValue = PainlessLookupUtility.defTypeToObjectType(rtn); } else if (Modifier.isStatic(modifiers)) { // static method: straightforward copy params = new Class[arguments.size()]; for (int i = 0; i < arguments.size(); i++) { - params[i] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(arguments.get(i)); + params[i] = PainlessLookupUtility.defTypeToObjectType(arguments.get(i)); } - returnValue = PainlessLookupUtility.painlessDefTypeToJavaObjectType(rtn); + returnValue = PainlessLookupUtility.defTypeToObjectType(rtn); } else if ("".equals(name)) { // constructor: returns the owner class params = new Class[arguments.size()]; for (int i = 0; i < arguments.size(); i++) { - params[i] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(arguments.get(i)); + params[i] = PainlessLookupUtility.defTypeToObjectType(arguments.get(i)); } returnValue = target; } else { @@ -92,9 +92,9 @@ public MethodType getMethodType() { params = new Class[1 + arguments.size()]; params[0] = target; for (int i = 0; i < arguments.size(); i++) { - params[i + 1] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(arguments.get(i)); + params[i + 1] = PainlessLookupUtility.defTypeToObjectType(arguments.get(i)); } - returnValue = PainlessLookupUtility.painlessDefTypeToJavaObjectType(rtn); + returnValue = PainlessLookupUtility.defTypeToObjectType(rtn); } return MethodType.methodType(returnValue, params); } 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 dd813f73c3dfc..1c6c0ef10db97 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 @@ -157,7 +157,7 @@ AExpression cast(Locals locals) { return ecast; } else { - if (PainlessLookupUtility.isAnyTypeConstant(expected)) { + if (PainlessLookupUtility.isConstantPainlessType(expected)) { // For the case where a cast is required, a constant is set, // and the constant can be immediately cast to the expected type. // An EConstant replaces this node with the constant cast appropriately 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 65776ca76f117..1a5b6a9cf37f1 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 @@ -106,8 +106,8 @@ private void analyzeMul(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply multiply [*] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } actual = promote; @@ -149,8 +149,8 @@ private void analyzeDiv(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply divide [/] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } actual = promote; @@ -197,8 +197,8 @@ private void analyzeRem(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply remainder [%] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } actual = promote; @@ -245,8 +245,8 @@ private void analyzeAdd(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply add [+] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } actual = promote; @@ -304,8 +304,8 @@ private void analyzeSub(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply subtract [-] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } actual = promote; @@ -363,8 +363,8 @@ private void analyzeLSH(Locals variables) { if (lhspromote == null || rhspromote == null) { throw createError(new ClassCastException("Cannot apply left shift [<<] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } actual = promote = lhspromote; @@ -411,8 +411,8 @@ private void analyzeRSH(Locals variables) { if (lhspromote == null || rhspromote == null) { throw createError(new ClassCastException("Cannot apply right shift [>>] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } actual = promote = lhspromote; @@ -462,8 +462,8 @@ private void analyzeUSH(Locals variables) { if (lhspromote == null || rhspromote == null) { throw createError(new ClassCastException("Cannot apply unsigned shift [>>>] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } if (lhspromote == def.class || rhspromote == def.class) { @@ -506,8 +506,8 @@ private void analyzeBWAnd(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply and [&] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } actual = promote; @@ -546,8 +546,8 @@ private void analyzeXor(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply xor [^] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } actual = promote; @@ -587,8 +587,8 @@ private void analyzeBWOr(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply or [|] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } actual = promote; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECapturingFunctionRef.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECapturingFunctionRef.java index e8ad9d85ed698..3e7cbeab74986 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECapturingFunctionRef.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECapturingFunctionRef.java @@ -69,7 +69,7 @@ void analyze(Locals locals) { defPointer = "D" + variable + "." + call + ",1"; } else { // typed implementation - defPointer = "S" + PainlessLookupUtility.anyTypeToPainlessTypeName(captured.clazz) + "." + call + ",1"; + defPointer = "S" + PainlessLookupUtility.painlessTypeToPainlessTypeName(captured.clazz) + "." + call + ",1"; } actual = String.class; } else { @@ -77,8 +77,8 @@ void analyze(Locals locals) { // static case if (captured.clazz != def.class) { try { - ref = new FunctionRef( - locals.getPainlessLookup(), expected, PainlessLookupUtility.anyTypeToPainlessTypeName(captured.clazz), call, 1); + ref = new FunctionRef(locals.getPainlessLookup(), expected, + PainlessLookupUtility.painlessTypeToPainlessTypeName(captured.clazz), call, 1); // check casts between the interface method and the delegate method are legal for (int i = 0; i < ref.interfaceMethod.arguments.size(); ++i) { @@ -110,7 +110,7 @@ void write(MethodWriter writer, Globals globals) { // typed interface, dynamic implementation writer.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot()); Type methodType = Type.getMethodType(MethodWriter.getType(expected), MethodWriter.getType(captured.clazz)); - writer.invokeDefCall(call, methodType, DefBootstrap.REFERENCE, PainlessLookupUtility.anyTypeToPainlessTypeName(expected)); + writer.invokeDefCall(call, methodType, DefBootstrap.REFERENCE, PainlessLookupUtility.painlessTypeToPainlessTypeName(expected)); } else { // typed interface, typed implementation writer.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot()); 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 b0451b685b57d..7990e5b41aa7e 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 @@ -63,6 +63,6 @@ void write(MethodWriter writer, Globals globals) { @Override public String toString() { - return singleLineToString(PainlessLookupUtility.anyTypeToPainlessTypeName(cast.to), child); + return singleLineToString(PainlessLookupUtility.painlessTypeToPainlessTypeName(cast.to), child); } } 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 edf18f501bc77..7e09c20467235 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 @@ -93,8 +93,8 @@ private void analyzeEq(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply equals [==] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } if (promotedType == def.class) { @@ -143,8 +143,8 @@ private void analyzeEqR(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply reference equals [===] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } left.expected = promotedType; @@ -184,8 +184,8 @@ private void analyzeNE(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply not equals [!=] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } if (promotedType == def.class) { @@ -234,8 +234,8 @@ private void analyzeNER(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply reference not equals [!==] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } left.expected = promotedType; @@ -275,8 +275,8 @@ private void analyzeGTE(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply greater than or equals [>=] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } if (promotedType == def.class) { @@ -315,8 +315,8 @@ private void analyzeGT(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply greater than [>] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } if (promotedType == def.class) { @@ -355,8 +355,8 @@ private void analyzeLTE(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply less than or equals [<=] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } if (promotedType == def.class) { @@ -395,8 +395,8 @@ private void analyzeLT(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply less than [>=] to types " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); } if (promotedType == def.class) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EFunctionRef.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EFunctionRef.java index 92b14a885a141..1f2fda47ddcb8 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EFunctionRef.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EFunctionRef.java @@ -68,13 +68,13 @@ void analyze(Locals locals) { PainlessMethod interfaceMethod = locals.getPainlessLookup().getPainlessStructFromJavaClass(expected).functionalMethod; if (interfaceMethod == null) { throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " + - "to [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "], not a functional interface"); + "to [" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expected) + "], not a functional interface"); } PainlessMethod delegateMethod = locals.getMethod(PainlessLookupUtility.buildPainlessMethodKey(call, interfaceMethod.arguments.size())); if (delegateMethod == null) { throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " + - "to [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "], function not found"); + "to [" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expected) + "], function not found"); } ref = new FunctionRef(expected, interfaceMethod, delegateMethod, 0); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java index 05564a2952e6f..959fcb2ac059c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java @@ -64,8 +64,8 @@ void analyze(Locals locals) { } // map to wrapped type for primitive types - resolvedType = clazz.isPrimitive() ? PainlessLookupUtility.getBoxedAnyType(clazz) : - PainlessLookupUtility.painlessDefTypeToJavaObjectType(clazz); + resolvedType = clazz.isPrimitive() ? PainlessLookupUtility.toBoxedPainlessType(clazz) : + PainlessLookupUtility.defTypeToObjectType(clazz); // analyze and cast the expression expression.analyze(locals); @@ -76,7 +76,7 @@ void analyze(Locals locals) { primitiveExpression = expression.actual.isPrimitive(); // map to wrapped type for primitive types expressionType = expression.actual.isPrimitive() ? - PainlessLookupUtility.getBoxedAnyType(expression.actual) : PainlessLookupUtility.painlessDefTypeToJavaObjectType(clazz); + PainlessLookupUtility.toBoxedPainlessType(expression.actual) : PainlessLookupUtility.defTypeToObjectType(clazz); actual = boolean.class; } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ELambda.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ELambda.java index 8e8d164b03d62..f8d38b0f20199 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ELambda.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ELambda.java @@ -123,12 +123,12 @@ void analyze(Locals locals) { interfaceMethod = locals.getPainlessLookup().getPainlessStructFromJavaClass(expected).functionalMethod; if (interfaceMethod == null) { throw createError(new IllegalArgumentException("Cannot pass lambda to " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "], not a functional interface")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expected) + "], not a functional interface")); } // check arity before we manipulate parameters if (interfaceMethod.arguments.size() != paramTypeStrs.size()) throw new IllegalArgumentException("Incorrect number of parameters for [" + interfaceMethod.name + - "] in [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "]"); + "] in [" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expected) + "]"); // for method invocation, its allowed to ignore the return value if (interfaceMethod.rtn == void.class) { returnType = def.class; @@ -140,7 +140,7 @@ void analyze(Locals locals) { for (int i = 0; i < paramTypeStrs.size(); i++) { String paramType = paramTypeStrs.get(i); if (paramType == null) { - actualParamTypeStrs.add(PainlessLookupUtility.anyTypeToPainlessTypeName(interfaceMethod.arguments.get(i))); + actualParamTypeStrs.add(PainlessLookupUtility.painlessTypeToPainlessTypeName(interfaceMethod.arguments.get(i))); } else { actualParamTypeStrs.add(paramType); } @@ -162,14 +162,14 @@ void analyze(Locals locals) { List paramTypes = new ArrayList<>(captures.size() + actualParamTypeStrs.size()); List paramNames = new ArrayList<>(captures.size() + paramNameStrs.size()); for (Variable var : captures) { - paramTypes.add(PainlessLookupUtility.anyTypeToPainlessTypeName(var.clazz)); + paramTypes.add(PainlessLookupUtility.painlessTypeToPainlessTypeName(var.clazz)); paramNames.add(var.name); } paramTypes.addAll(actualParamTypeStrs); paramNames.addAll(paramNameStrs); // desugar lambda body into a synthetic method - desugared = new SFunction(reserved, location, PainlessLookupUtility.anyTypeToPainlessTypeName(returnType), name, + desugared = new SFunction(reserved, location, PainlessLookupUtility.painlessTypeToPainlessTypeName(returnType), name, paramTypes, paramNames, statements, true); desugared.generateSignature(locals.getPainlessLookup()); desugared.analyze(Locals.newLambdaScope(locals.getProgramScope(), returnType, 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 6bc5331cb1d84..de2a21ae3c509 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 @@ -53,7 +53,7 @@ void analyze(Locals locals) { if (expected != null) { if (expected.isPrimitive()) { throw createError(new IllegalArgumentException( - "Cannot cast null to a primitive type [" + PainlessLookupUtility.anyTypeToPainlessTypeName(expected) + "].")); + "Cannot cast null to a primitive type [" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expected) + "].")); } actual = expected; 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 d34399db779df..78f2a5c4ee19b 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 @@ -94,7 +94,7 @@ void analyzeBWNot(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply not [~] to type " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(child.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(child.actual) + "].")); } child.expected = promote; @@ -124,7 +124,7 @@ void analyzerAdd(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply positive [+] to type " + - "[" + PainlessLookupUtility.painlessDefTypeToJavaObjectType(child.actual) + "].")); + "[" + PainlessLookupUtility.defTypeToObjectType(child.actual) + "].")); } child.expected = promote; @@ -158,7 +158,7 @@ void analyzerSub(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply negative [-] to type " + - "[" + PainlessLookupUtility.painlessDefTypeToJavaObjectType(child.actual) + "].")); + "[" + PainlessLookupUtility.defTypeToObjectType(child.actual) + "].")); } child.expected = promote; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java index c45107a37ac21..40d1c8d577abc 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java @@ -68,7 +68,7 @@ void analyze(Locals locals) { sub = new PSubListShortcut(location, locals.getPainlessLookup().getPainlessStructFromJavaClass(prefix.actual), index); } else { throw createError(new IllegalArgumentException("Illegal array access on type " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(prefix.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(prefix.actual) + "].")); } sub.write = write; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java index cd5d648379193..01063831c2d29 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java @@ -73,7 +73,7 @@ void analyze(Locals locals) { PainlessClass struct = locals.getPainlessLookup().getPainlessStructFromJavaClass(prefix.actual); if (prefix.actual.isPrimitive()) { - struct = locals.getPainlessLookup().getPainlessStructFromJavaClass(PainlessLookupUtility.getBoxedAnyType(prefix.actual)); + struct = locals.getPainlessLookup().getPainlessStructFromJavaClass(PainlessLookupUtility.toBoxedPainlessType(prefix.actual)); } String methodKey = PainlessLookupUtility.buildPainlessMethodKey(name, arguments.size()); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java index b5df74358d3e6..a21bbcc5d2fe4 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java @@ -63,7 +63,7 @@ void analyze(Locals locals) { prefix = prefix.cast(locals); if (prefix.actual.isArray()) { - sub = new PSubArrayLength(location, PainlessLookupUtility.anyTypeToPainlessTypeName(prefix.actual), value); + sub = new PSubArrayLength(location, PainlessLookupUtility.painlessTypeToPainlessTypeName(prefix.actual), value); } else if (prefix.actual == def.class) { sub = new PSubDefField(location, value); } else { @@ -85,7 +85,8 @@ void analyze(Locals locals) { "set" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 1)); if (getter != null || setter != null) { - sub = new PSubShortcut(location, value, PainlessLookupUtility.anyTypeToPainlessTypeName(prefix.actual), getter, setter); + sub = new PSubShortcut( + location, value, PainlessLookupUtility.painlessTypeToPainlessTypeName(prefix.actual), getter, setter); } else { EConstant index = new EConstant(location, value); index.analyze(locals); @@ -103,7 +104,7 @@ void analyze(Locals locals) { if (sub == null) { throw createError(new IllegalArgumentException( - "Unknown field [" + value + "] for type [" + PainlessLookupUtility.anyTypeToPainlessTypeName(prefix.actual) + "].")); + "Unknown field [" + value + "] for type [" + PainlessLookupUtility.painlessTypeToPainlessTypeName(prefix.actual) + "].")); } if (nullSafe) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubField.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubField.java index a1a0ee1dade36..4cb3d83666367 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubField.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubField.java @@ -53,7 +53,7 @@ void extractVariables(Set variables) { void analyze(Locals locals) { if (write && Modifier.isFinal(field.modifiers)) { throw createError(new IllegalArgumentException("Cannot write to read-only field [" + field.name + "] for type " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(field.clazz) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(field.clazz) + "].")); } actual = field.clazz; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java index de1a7062a24f2..fb91b076574f5 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java @@ -85,7 +85,7 @@ void analyze(Locals locals) { sub = new SSubEachIterable(location, variable, expression, block); } else { throw createError(new IllegalArgumentException("Illegal for each type " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(expression.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expression.actual) + "].")); } sub.analyze(locals); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFunction.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFunction.java index 1c801d509b581..37978d884a6e7 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFunction.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFunction.java @@ -136,7 +136,7 @@ void generateSignature(PainlessLookup painlessLookup) { try { Class paramType = painlessLookup.getJavaClassFromPainlessType(this.paramTypeStrs.get(param)); - paramClasses[param] = PainlessLookupUtility.painlessDefTypeToJavaObjectType(paramType); + paramClasses[param] = PainlessLookupUtility.defTypeToObjectType(paramType); paramTypes.add(paramType); parameters.add(new Parameter(location, paramNameStrs.get(param), paramType)); } catch (IllegalArgumentException exception) { @@ -146,7 +146,7 @@ void generateSignature(PainlessLookup painlessLookup) { } org.objectweb.asm.commons.Method method = new org.objectweb.asm.commons.Method(name, MethodType.methodType( - PainlessLookupUtility.painlessDefTypeToJavaObjectType(rtnType), paramClasses).toMethodDescriptorString()); + PainlessLookupUtility.defTypeToObjectType(rtnType), paramClasses).toMethodDescriptorString()); this.method = new PainlessMethod(name, null, null, rtnType, paramTypes, method, Modifier.STATIC | Modifier.PRIVATE, null); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachArray.java index fea8c8953b67f..655547a066287 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachArray.java @@ -109,6 +109,6 @@ void write(MethodWriter writer, Globals globals) { @Override public String toString() { - return singleLineToString(PainlessLookupUtility.anyTypeToPainlessTypeName(variable.clazz), variable.name, expression, block); + return singleLineToString(PainlessLookupUtility.painlessTypeToPainlessTypeName(variable.clazz), variable.name, expression, block); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachIterable.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachIterable.java index 798b30e2b6d51..e02a2bfdf2b54 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachIterable.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachIterable.java @@ -81,7 +81,7 @@ void analyze(Locals locals) { if (method == null) { throw createError(new IllegalArgumentException("Unable to create iterator for the type " + - "[" + PainlessLookupUtility.anyTypeToPainlessTypeName(expression.actual) + "].")); + "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expression.actual) + "].")); } } @@ -132,6 +132,6 @@ void write(MethodWriter writer, Globals globals) { @Override public String toString() { - return singleLineToString(PainlessLookupUtility.anyTypeToPainlessTypeName(variable.clazz), variable.name, expression, block); + return singleLineToString(PainlessLookupUtility.painlessTypeToPainlessTypeName(variable.clazz), variable.name, expression, block); } } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/PainlessDocGenerator.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/PainlessDocGenerator.java index cc596dcc39564..31473a554c6d8 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/PainlessDocGenerator.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/PainlessDocGenerator.java @@ -210,7 +210,7 @@ private static void documentMethod(PrintStream stream, PainlessMethod method) { */ private static void emitAnchor(PrintStream stream, Class clazz) { stream.print("painless-api-reference-"); - stream.print(PainlessLookupUtility.anyTypeToPainlessTypeName(clazz).replace('.', '-')); + stream.print(PainlessLookupUtility.painlessTypeToPainlessTypeName(clazz).replace('.', '-')); } /** @@ -234,7 +234,7 @@ private static void emitAnchor(PrintStream stream, PainlessField field) { } private static String methodName(PainlessMethod method) { - return method.name.equals("") ? PainlessLookupUtility.anyTypeToPainlessTypeName(method.target) : method.name; + return method.name.equals("") ? PainlessLookupUtility.painlessTypeToPainlessTypeName(method.target) : method.name; } /** From 05804659dc86b92ab25ad0db6f54f265856ddc1d Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Wed, 18 Jul 2018 14:26:40 -0700 Subject: [PATCH 2/4] Quick fix. --- .../elasticsearch/painless/lookup/PainlessLookupUtility.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java index 1fc87c83c479e..726c2e647c610 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java @@ -167,7 +167,7 @@ public static Class ObjectTypeTodefType(Class painlessType) { Arrays.fill(arrayBraces, '['); try { - return Class.forName(new String(arrayBraces) + def.class.getName() + ";"); + return Class.forName(new String(arrayBraces) + "L" + def.class.getName() + ";"); } catch (ClassNotFoundException cnfe) { throw new IllegalStateException("internal error", cnfe); } @@ -196,7 +196,7 @@ public static Class defTypeToObjectType(Class painlessType) { Arrays.fill(arrayBraces, '['); try { - return Class.forName(new String(arrayBraces) + Object.class.getName() + ";"); + return Class.forName(new String(arrayBraces) + "L" + Object.class.getName() + ";"); } catch (ClassNotFoundException cnfe) { throw new IllegalStateException("internal error", cnfe); } From 53809f1cd28c796e256be98acd21085b68eea414 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Thu, 19 Jul 2018 12:11:56 -0700 Subject: [PATCH 3/4] More renaming. --- .../painless/AnalyzerCaster.java | 4 +- .../java/org/elasticsearch/painless/Def.java | 6 +- .../elasticsearch/painless/FunctionRef.java | 2 +- .../org/elasticsearch/painless/Locals.java | 2 +- .../painless/ScriptClassInfo.java | 2 +- .../painless/lookup/PainlessLookup.java | 2 +- .../lookup/PainlessLookupBuilder.java | 221 +++++++------- .../lookup/PainlessLookupUtility.java | 269 +++++++++--------- .../painless/lookup/PainlessMethod.java | 14 +- .../painless/node/AExpression.java | 2 +- .../elasticsearch/painless/node/EBinary.java | 44 +-- .../painless/node/ECapturingFunctionRef.java | 6 +- .../elasticsearch/painless/node/ECast.java | 2 +- .../elasticsearch/painless/node/EComp.java | 32 +-- .../painless/node/EFunctionRef.java | 4 +- .../painless/node/EInstanceof.java | 6 +- .../elasticsearch/painless/node/ELambda.java | 10 +- .../elasticsearch/painless/node/ENull.java | 2 +- .../elasticsearch/painless/node/EUnary.java | 6 +- .../elasticsearch/painless/node/PBrace.java | 2 +- .../painless/node/PCallInvoke.java | 2 +- .../elasticsearch/painless/node/PField.java | 6 +- .../painless/node/PSubField.java | 2 +- .../elasticsearch/painless/node/SEach.java | 2 +- .../painless/node/SFunction.java | 4 +- .../painless/node/SSubEachArray.java | 2 +- .../painless/node/SSubEachIterable.java | 4 +- .../painless/PainlessDocGenerator.java | 4 +- 28 files changed, 329 insertions(+), 335 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 ddcae5abb6991..fe53a3c11001c 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 @@ -466,8 +466,8 @@ public static PainlessCast getLegalCast(Location location, Class actual, Clas return PainlessCast.standard(actual, expected, explicit); } else { throw location.createError(new ClassCastException("Cannot cast from " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(actual) + "] to " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expected) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(actual) + "] to " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "].")); } } 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 27f64e2a0d7d2..dad8da06e76b1 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 @@ -302,7 +302,7 @@ static MethodHandle lookupMethod(PainlessLookup painlessLookup, MethodHandles.Lo nestedType, 0, DefBootstrap.REFERENCE, - PainlessLookupUtility.painlessTypeToPainlessTypeName(interfaceType)); + PainlessLookupUtility.typeToCanonicalTypeName(interfaceType)); filter = nested.dynamicInvoker(); } else { throw new AssertionError(); @@ -334,7 +334,7 @@ static MethodHandle lookupReference(PainlessLookup painlessLookup, MethodHandles int arity = interfaceMethod.arguments.size(); PainlessMethod implMethod = lookupMethodInternal(painlessLookup, receiverClass, name, arity); return lookupReferenceInternal(painlessLookup, methodHandlesLookup, interfaceType, - PainlessLookupUtility.painlessTypeToPainlessTypeName(implMethod.target), implMethod.name, receiverClass); + PainlessLookupUtility.typeToCanonicalTypeName(implMethod.target), implMethod.name, receiverClass); } /** Returns a method handle to an implementation of clazz, given method reference signature. */ @@ -347,7 +347,7 @@ private static MethodHandle lookupReferenceInternal(PainlessLookup painlessLooku PainlessMethod interfaceMethod = painlessLookup.getPainlessStructFromJavaClass(clazz).functionalMethod; if (interfaceMethod == null) { throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " + - "to [" + PainlessLookupUtility.painlessTypeToPainlessTypeName(clazz) + "], not a functional interface"); + "to [" + PainlessLookupUtility.typeToCanonicalTypeName(clazz) + "], not a functional interface"); } int arity = interfaceMethod.arguments.size() + captures.length; final MethodHandle handle; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/FunctionRef.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/FunctionRef.java index bf574ee0f4c1f..aa72724b93029 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/FunctionRef.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/FunctionRef.java @@ -168,7 +168,7 @@ private static PainlessMethod lookup(PainlessLookup painlessLookup, Class exp PainlessMethod method = painlessLookup.getPainlessStructFromJavaClass(expected).functionalMethod; if (method == null) { throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " + - "to [" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expected) + "], not a functional interface"); + "to [" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "], not a functional interface"); } // lookup requested method diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Locals.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Locals.java index d977774ef7bc3..804f6aa2b689c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/Locals.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/Locals.java @@ -292,7 +292,7 @@ public int getSlot() { @Override public String toString() { StringBuilder b = new StringBuilder(); - b.append("Variable[type=").append(PainlessLookupUtility.painlessTypeToPainlessTypeName(clazz)); + b.append("Variable[type=").append(PainlessLookupUtility.typeToCanonicalTypeName(clazz)); b.append(",name=").append(name); b.append(",slot=").append(slot); if (readonly) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java index df13d22cc690b..6d4b455269616 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/ScriptClassInfo.java @@ -183,7 +183,7 @@ private MethodArgument methodArgument(PainlessLookup painlessLookup, Class cl private static Class definitionTypeForClass(PainlessLookup painlessLookup, Class type, Function, String> unknownErrorMessageSource) { - type = PainlessLookupUtility.ObjectTypeTodefType(type); + type = PainlessLookupUtility.javaTypeToType(type); Class componentType = type; while (componentType.isArray()) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookup.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookup.java index 6111d12317b18..752c0c205dd89 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookup.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookup.java @@ -54,6 +54,6 @@ public PainlessClass getPainlessStructFromJavaClass(Class clazz) { } public Class getJavaClassFromPainlessType(String painlessType) { - return PainlessLookupUtility.painlessTypeNameToPainlessType(painlessType, painlessTypesToJavaClasses); + return PainlessLookupUtility.canonicalTypeNameToType(painlessType, painlessTypesToJavaClasses); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupBuilder.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupBuilder.java index d2a6dc42f15b1..365a5b12a0d9c 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupBuilder.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupBuilder.java @@ -38,22 +38,21 @@ import java.util.Stack; import java.util.regex.Pattern; -import static org.elasticsearch.painless.lookup.PainlessLookupUtility.DEF_PAINLESS_TYPE_NAME; +import static org.elasticsearch.painless.lookup.PainlessLookupUtility.DEF_TYPE_NAME; import static org.elasticsearch.painless.lookup.PainlessLookupUtility.buildPainlessMethodKey; -import static org.elasticsearch.painless.lookup.PainlessLookupUtility.javaTypeNameToPainlessTypeName; public class PainlessLookupBuilder { private static class PainlessMethodCacheKey { - private final Class painlessType; + private final Class targetType; private final String methodName; - private final List> painlessTypeParameters; + private final List> typeParameters; - private PainlessMethodCacheKey(Class painlessType, String methodName, List> painlessTypeParameters) { - this.painlessType = painlessType; + private PainlessMethodCacheKey(Class targetType, String methodName, List> typeParameters) { + this.targetType = targetType; this.methodName = methodName; - this.painlessTypeParameters = Collections.unmodifiableList(painlessTypeParameters); + this.typeParameters = Collections.unmodifiableList(typeParameters); } @Override @@ -68,27 +67,27 @@ public boolean equals(Object object) { PainlessMethodCacheKey that = (PainlessMethodCacheKey)object; - return Objects.equals(painlessType, that.painlessType) && - Objects.equals(methodName, that.methodName) && - Objects.equals(painlessTypeParameters, that.painlessTypeParameters); + return Objects.equals(targetType, that.targetType) && + Objects.equals(methodName, that.methodName) && + Objects.equals(typeParameters, that.typeParameters); } @Override public int hashCode() { - return Objects.hash(painlessType, methodName, painlessTypeParameters); + return Objects.hash(targetType, methodName, typeParameters); } } private static class PainlessFieldCacheKey { - private final Class painlessType; + private final Class targetType; private final String fieldName; - private final Class painlessTypeParameter; + private final Class typeParameter; - private PainlessFieldCacheKey(Class painlessType, String fieldName, Class painlessTypeParameter) { - this.painlessType = painlessType; + private PainlessFieldCacheKey(Class targetType, String fieldName, Class typeParameter) { + this.targetType = targetType; this.fieldName = fieldName; - this.painlessTypeParameter = painlessTypeParameter; + this.typeParameter = typeParameter; } @Override @@ -103,14 +102,14 @@ public boolean equals(Object object) { PainlessFieldCacheKey that = (PainlessFieldCacheKey) object; - return Objects.equals(painlessType, that.painlessType) && - Objects.equals(fieldName, that.fieldName) && - Objects.equals(painlessTypeParameter, that.painlessTypeParameter); + return Objects.equals(targetType, that.targetType) && + Objects.equals(fieldName, that.fieldName) && + Objects.equals(typeParameter, that.typeParameter); } @Override public int hashCode() { - return Objects.hash(painlessType, fieldName, painlessTypeParameter); + return Objects.hash(targetType, fieldName, typeParameter); } } @@ -123,129 +122,113 @@ public int hashCode() { private final List whitelists; - private final Map> painlessTypeNamesToPainlessTypes; - private final Map, PainlessClassBuilder> painlessTypesToPainlessClasses; + private final Map> canonicalTypeNamesToClasses; + private final Map, PainlessClassBuilder> classesToPainlessClasses; public PainlessLookupBuilder(List whitelists) { this.whitelists = whitelists; - painlessTypeNamesToPainlessTypes = new HashMap<>(); - painlessTypesToPainlessClasses = new HashMap<>(); + canonicalTypeNamesToClasses = new HashMap<>(); + classesToPainlessClasses = new HashMap<>(); - painlessTypeNamesToPainlessTypes.put(DEF_PAINLESS_TYPE_NAME, def.class); - painlessTypesToPainlessClasses.put(def.class, - new PainlessClassBuilder(DEF_PAINLESS_TYPE_NAME, Object.class, Type.getType(Object.class))); + canonicalTypeNamesToClasses.put(DEF_TYPE_NAME, def.class); + classesToPainlessClasses.put(def.class, + new PainlessClassBuilder(DEF_TYPE_NAME, Object.class, Type.getType(Object.class))); } - private Class painlessTypeNameToPainlessType(String painlessTypeName) { - return PainlessLookupUtility.painlessTypeNameToPainlessType(painlessTypeName, painlessTypeNamesToPainlessTypes); + private Class canonicalTypeNameToType(String canonicalTypeName) { + return PainlessLookupUtility.canonicalTypeNameToType(canonicalTypeName, canonicalTypeNamesToClasses); } - private void validatePainlessType(Class painlessType) { - PainlessLookupUtility.validatePainlessType(painlessType, painlessTypesToPainlessClasses.keySet()); + private void validateType(Class type) { + PainlessLookupUtility.validateType(type, classesToPainlessClasses.keySet()); } - public void addPainlessClass(ClassLoader classLoader, String javaTypeName, boolean importPainlessTypeName) { + public void addPainlessClass(ClassLoader classLoader, String javaClassName, boolean importClassName) { Objects.requireNonNull(classLoader); - Objects.requireNonNull(javaTypeName); - - String painlessTypeName = javaTypeNameToPainlessTypeName(javaTypeName); - - if (CLASS_NAME_PATTERN.matcher(painlessTypeName).matches() == false) { - throw new IllegalArgumentException("invalid painless type name [" + painlessTypeName + "]"); - } - - String importedPainlessTypeName = javaTypeNameToPainlessTypeName(javaTypeName.substring(javaTypeName.lastIndexOf('.') + 1)); - - Class painlessType; - - if ("void".equals(javaTypeName)) painlessType = void.class; - else if ("boolean".equals(javaTypeName)) painlessType = boolean.class; - else if ("byte".equals(javaTypeName)) painlessType = byte.class; - else if ("short".equals(javaTypeName)) painlessType = short.class; - else if ("char".equals(javaTypeName)) painlessType = char.class; - else if ("int".equals(javaTypeName)) painlessType = int.class; - else if ("long".equals(javaTypeName)) painlessType = long.class; - else if ("float".equals(javaTypeName)) painlessType = float.class; - else if ("double".equals(javaTypeName)) painlessType = double.class; + Objects.requireNonNull(javaClassName); + + Class clazz; + + if ("void".equals(javaClassName)) clazz = void.class; + else if ("boolean".equals(javaClassName)) clazz = boolean.class; + else if ("byte".equals(javaClassName)) clazz = byte.class; + else if ("short".equals(javaClassName)) clazz = short.class; + else if ("char".equals(javaClassName)) clazz = char.class; + else if ("int".equals(javaClassName)) clazz = int.class; + else if ("long".equals(javaClassName)) clazz = long.class; + else if ("float".equals(javaClassName)) clazz = float.class; + else if ("double".equals(javaClassName)) clazz = double.class; else { try { - painlessType = Class.forName(javaTypeName, true, classLoader); - - if (painlessType == def.class) { - throw new IllegalArgumentException("cannot add reserved painless type [" + DEF_PAINLESS_TYPE_NAME + "]"); - } + clazz = Class.forName(javaClassName, true, classLoader); } catch (ClassNotFoundException cnfe) { - throw new IllegalArgumentException("java type [" + javaTypeName + "] not found", cnfe); + throw new IllegalArgumentException("class [" + javaClassName + "] not found", cnfe); } } - addPainlessClass(painlessTypeName, importedPainlessTypeName, painlessType, importPainlessTypeName); + addPainlessClass(clazz, importClassName); } - public void addPainlessClass(Class painlessType, boolean importPainlessTypeName) { - Objects.requireNonNull(painlessType); + public void addPainlessClass(Class clazz, boolean importClassName) { + Objects.requireNonNull(clazz); - if (painlessType == def.class) { - throw new IllegalArgumentException("cannot add reserved painless type [" + DEF_PAINLESS_TYPE_NAME + "]"); + if (clazz == def.class) { + throw new IllegalArgumentException("cannot add reserved class [" + DEF_TYPE_NAME + "]"); } - String javaTypeName = painlessType.getCanonicalName(); - String painlessTypeName = javaTypeNameToPainlessTypeName(javaTypeName); + String canonicalClassName = clazz.getCanonicalName(); - if (painlessType.isArray()) { - throw new IllegalArgumentException("invalid painless type name [" + painlessTypeName + "]"); + if (clazz.isArray()) { + throw new IllegalArgumentException("cannot add array type [" + canonicalClassName + "] as a class"); } - String importedPainlessTypeName = javaTypeNameToPainlessTypeName(javaTypeName.substring(javaTypeName.lastIndexOf('.') + 1)); - - addPainlessClass(painlessTypeName, importedPainlessTypeName, painlessType, importPainlessTypeName); - } - - private void addPainlessClass( - String painlessTypeName, String importedPainlessTypeName, Class painlessType, boolean importPainlessClassName) { + if (CLASS_NAME_PATTERN.matcher(canonicalClassName).matches() == false) { + throw new IllegalArgumentException("invalid class name [" + canonicalClassName + "]"); + } - PainlessClassBuilder existingPainlessClassBuilder = painlessTypesToPainlessClasses.get(painlessType); + PainlessClassBuilder existingPainlessClassBuilder = classesToPainlessClasses.get(clazz); if (existingPainlessClassBuilder == null) { - PainlessClassBuilder painlessClassBuilder = - new PainlessClassBuilder(painlessTypeName, painlessType, Type.getType(painlessType)); + PainlessClassBuilder painlessClassBuilder = new PainlessClassBuilder(canonicalClassName, clazz, Type.getType(clazz)); - painlessTypeNamesToPainlessTypes.put(painlessTypeName, painlessType); - painlessTypesToPainlessClasses.put(painlessType, painlessClassBuilder); - } else if (existingPainlessClassBuilder.clazz.equals(painlessType) == false) { - throw new IllegalArgumentException("painless type [" + painlessTypeName + "] illegally represents multiple java types " + - "[" + painlessType.getCanonicalName() + "] and [" + existingPainlessClassBuilder.clazz.getCanonicalName() + "]"); + canonicalTypeNamesToClasses.put(canonicalClassName, clazz); + classesToPainlessClasses.put(clazz, painlessClassBuilder); + } else if (existingPainlessClassBuilder.clazz.equals(clazz) == false) { + throw new IllegalArgumentException("class [" + canonicalClassName + "] " + + "cannot represent multiple java classes with the same name from different class loaders"); } - if (painlessTypeName.equals(importedPainlessTypeName)) { - if (importPainlessClassName == true) { - throw new IllegalArgumentException( - "must use only_fqn parameter on painless type [" + painlessTypeName + "] with no package"); + String javaClassName = clazz.getName(); + String importedCanonicalClassName = javaClassName.substring(javaClassName.lastIndexOf('.') + 1).replace('$', '.'); + + if (canonicalClassName.equals(importedCanonicalClassName)) { + if (importClassName == true) { + throw new IllegalArgumentException("must use only_fqn parameter on class [" + canonicalClassName + "] with no package"); } } else { - Class importedPainlessType = painlessTypeNamesToPainlessTypes.get(importedPainlessTypeName); + Class importedPainlessType = canonicalTypeNamesToClasses.get(importedCanonicalClassName); if (importedPainlessType == null) { - if (importPainlessClassName) { + if (importClassName) { if (existingPainlessClassBuilder != null) { throw new IllegalArgumentException( - "inconsistent only_fqn parameters found for painless type [" + painlessTypeName + "]"); + "inconsistent only_fqn parameters found for painless type [" + canonicalClassName + "]"); } - painlessTypeNamesToPainlessTypes.put(importedPainlessTypeName, painlessType); + canonicalTypeNamesToClasses.put(importedCanonicalClassName, clazz); } - } else if (importedPainlessType.equals(painlessType) == false) { - throw new IllegalArgumentException("painless type [" + importedPainlessTypeName + "] illegally represents multiple " + - "java types [" + painlessType.getCanonicalName() + "] and [" + importedPainlessType.getCanonicalName() + "]"); - } else if (importPainlessClassName == false) { - throw new IllegalArgumentException("inconsistent only_fqn parameters found for painless type [" + painlessTypeName + "]"); + } else if (importedPainlessType.equals(clazz) == false) { + throw new IllegalArgumentException("painless type [" + importedCanonicalClassName + "] illegally represents multiple " + + "java types [" + clazz.getCanonicalName() + "] and [" + importedPainlessType.getCanonicalName() + "]"); + } else if (importClassName == false) { + throw new IllegalArgumentException("inconsistent only_fqn parameters found for painless type [" + canonicalClassName + "]"); } } } private void addConstructor(String ownerStructName, WhitelistConstructor whitelistConstructor) { - PainlessClassBuilder ownerStruct = painlessTypesToPainlessClasses.get(painlessTypeNamesToPainlessTypes.get(ownerStructName)); + PainlessClassBuilder ownerStruct = classesToPainlessClasses.get(canonicalTypeNamesToClasses.get(ownerStructName)); if (ownerStruct == null) { throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for constructor with " + @@ -259,10 +242,10 @@ private void addConstructor(String ownerStructName, WhitelistConstructor whiteli String painlessParameterTypeName = whitelistConstructor.painlessParameterTypeNames.get(parameterCount); try { - Class painlessParameterClass = painlessTypeNameToPainlessType(painlessParameterTypeName); + Class painlessParameterClass = canonicalTypeNameToType(painlessParameterTypeName); painlessParametersTypes.add(painlessParameterClass); - javaClassParameters[parameterCount] = PainlessLookupUtility.defTypeToObjectType(painlessParameterClass); + javaClassParameters[parameterCount] = PainlessLookupUtility.typeToJavaType(painlessParameterClass); } catch (IllegalArgumentException iae) { throw new IllegalArgumentException("struct not defined for constructor parameter [" + painlessParameterTypeName + "] " + "with owner struct [" + ownerStructName + "] and constructor parameters " + @@ -306,7 +289,7 @@ private void addConstructor(String ownerStructName, WhitelistConstructor whiteli } private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName, WhitelistMethod whitelistMethod) { - PainlessClassBuilder ownerStruct = painlessTypesToPainlessClasses.get(painlessTypeNamesToPainlessTypes.get(ownerStructName)); + PainlessClassBuilder ownerStruct = classesToPainlessClasses.get(canonicalTypeNamesToClasses.get(ownerStructName)); if (ownerStruct == null) { throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for method with " + @@ -345,11 +328,11 @@ private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName, String painlessParameterTypeName = whitelistMethod.painlessParameterTypeNames.get(parameterCount); try { - Class painlessParameterClass = painlessTypeNameToPainlessType(painlessParameterTypeName); + Class painlessParameterClass = canonicalTypeNameToType(painlessParameterTypeName); painlessParametersTypes.add(painlessParameterClass); javaClassParameters[parameterCount + augmentedOffset] = - PainlessLookupUtility.defTypeToObjectType(painlessParameterClass); + PainlessLookupUtility.typeToJavaType(painlessParameterClass); } catch (IllegalArgumentException iae) { throw new IllegalArgumentException("struct not defined for method parameter [" + painlessParameterTypeName + "] " + "with owner struct [" + ownerStructName + "] and method with name [" + whitelistMethod.javaMethodName + "] " + @@ -371,14 +354,14 @@ private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName, Class painlessReturnClass; try { - painlessReturnClass = painlessTypeNameToPainlessType(whitelistMethod.painlessReturnTypeName); + painlessReturnClass = canonicalTypeNameToType(whitelistMethod.painlessReturnTypeName); } catch (IllegalArgumentException iae) { throw new IllegalArgumentException("struct not defined for return type [" + whitelistMethod.painlessReturnTypeName + "] " + "with owner struct [" + ownerStructName + "] and method with name [" + whitelistMethod.javaMethodName + "] " + "and parameters " + whitelistMethod.painlessParameterTypeNames, iae); } - if (javaMethod.getReturnType() != PainlessLookupUtility.defTypeToObjectType(painlessReturnClass)) { + if (javaMethod.getReturnType() != PainlessLookupUtility.typeToJavaType(painlessReturnClass)) { throw new IllegalArgumentException("specified return type class [" + painlessReturnClass + "] " + "does not match the return type class [" + javaMethod.getReturnType() + "] for the " + "method with name [" + whitelistMethod.javaMethodName + "] " + @@ -444,7 +427,7 @@ private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName, } private void addField(String ownerStructName, WhitelistField whitelistField) { - PainlessClassBuilder ownerStruct = painlessTypesToPainlessClasses.get(painlessTypeNamesToPainlessTypes.get(ownerStructName)); + PainlessClassBuilder ownerStruct = classesToPainlessClasses.get(canonicalTypeNamesToClasses.get(ownerStructName)); if (ownerStruct == null) { throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for method with " + @@ -468,7 +451,7 @@ private void addField(String ownerStructName, WhitelistField whitelistField) { Class painlessFieldClass; try { - painlessFieldClass = painlessTypeNameToPainlessType(whitelistField.painlessFieldTypeName); + painlessFieldClass = canonicalTypeNameToType(whitelistField.painlessFieldTypeName); } catch (IllegalArgumentException iae) { throw new IllegalArgumentException("struct not defined for return type [" + whitelistField.painlessFieldTypeName + "] " + "with owner struct [" + ownerStructName + "] and field with name [" + whitelistField.javaFieldName + "]", iae); @@ -525,7 +508,7 @@ private void addField(String ownerStructName, WhitelistField whitelistField) { } private void copyStruct(String struct, List children) { - final PainlessClassBuilder owner = painlessTypesToPainlessClasses.get(painlessTypeNamesToPainlessTypes.get(struct)); + final PainlessClassBuilder owner = classesToPainlessClasses.get(canonicalTypeNamesToClasses.get(struct)); if (owner == null) { throw new IllegalArgumentException("Owner struct [" + struct + "] not defined for copy."); @@ -533,7 +516,7 @@ private void copyStruct(String struct, List children) { for (int count = 0; count < children.size(); ++count) { final PainlessClassBuilder child = - painlessTypesToPainlessClasses.get(painlessTypeNamesToPainlessTypes.get(children.get(count))); + classesToPainlessClasses.get(canonicalTypeNamesToClasses.get(children.get(count))); if (child == null) { throw new IllegalArgumentException("Child struct [" + children.get(count) + "]" + @@ -707,7 +690,7 @@ public PainlessLookup build() { for (WhitelistClass whitelistStruct : whitelist.whitelistStructs) { String painlessTypeName = whitelistStruct.javaClassName.replace('$', '.'); PainlessClassBuilder painlessStruct = - painlessTypesToPainlessClasses.get(painlessTypeNamesToPainlessTypes.get(painlessTypeName)); + classesToPainlessClasses.get(canonicalTypeNamesToClasses.get(painlessTypeName)); if (painlessStruct != null && painlessStruct.clazz.getName().equals(whitelistStruct.javaClassName) == false) { throw new IllegalArgumentException("struct [" + painlessStruct.name + "] cannot represent multiple classes " + @@ -718,8 +701,8 @@ public PainlessLookup build() { addPainlessClass( whitelist.javaClassLoader, whitelistStruct.javaClassName, whitelistStruct.onlyFQNJavaClassName == false); - painlessStruct = painlessTypesToPainlessClasses.get(painlessTypeNamesToPainlessTypes.get(painlessTypeName)); - painlessTypesToPainlessClasses.put(painlessStruct.clazz, painlessStruct); + painlessStruct = classesToPainlessClasses.get(canonicalTypeNamesToClasses.get(painlessTypeName)); + classesToPainlessClasses.put(painlessStruct.clazz, painlessStruct); } } @@ -752,8 +735,8 @@ public PainlessLookup build() { // goes through each Painless struct and determines the inheritance list, // and then adds all inherited types to the Painless struct's whitelist - for (Class javaClass : painlessTypesToPainlessClasses.keySet()) { - PainlessClassBuilder painlessStruct = painlessTypesToPainlessClasses.get(javaClass); + for (Class javaClass : classesToPainlessClasses.keySet()) { + PainlessClassBuilder painlessStruct = classesToPainlessClasses.get(javaClass); List painlessSuperStructs = new ArrayList<>(); Class javaSuperClass = painlessStruct.clazz.getSuperclass(); @@ -764,7 +747,7 @@ public PainlessLookup build() { // adds super classes to the inheritance list if (javaSuperClass != null && javaSuperClass.isInterface() == false) { while (javaSuperClass != null) { - PainlessClassBuilder painlessSuperStruct = painlessTypesToPainlessClasses.get(javaSuperClass); + PainlessClassBuilder painlessSuperStruct = classesToPainlessClasses.get(javaSuperClass); if (painlessSuperStruct != null) { painlessSuperStructs.add(painlessSuperStruct.name); @@ -780,7 +763,7 @@ public PainlessLookup build() { Class javaInterfaceLookup = javaInteraceLookups.pop(); for (Class javaSuperInterface : javaInterfaceLookup.getInterfaces()) { - PainlessClassBuilder painlessInterfaceStruct = painlessTypesToPainlessClasses.get(javaSuperInterface); + PainlessClassBuilder painlessInterfaceStruct = classesToPainlessClasses.get(javaSuperInterface); if (painlessInterfaceStruct != null) { String painlessInterfaceStructName = painlessInterfaceStruct.name; @@ -801,7 +784,7 @@ public PainlessLookup build() { // copies methods and fields from Object into interface types if (painlessStruct.clazz.isInterface() || (def.class.getSimpleName()).equals(painlessStruct.name)) { - PainlessClassBuilder painlessObjectStruct = painlessTypesToPainlessClasses.get(Object.class); + PainlessClassBuilder painlessObjectStruct = classesToPainlessClasses.get(Object.class); if (painlessObjectStruct != null) { copyStruct(painlessStruct.name, Collections.singletonList(painlessObjectStruct.name)); @@ -810,18 +793,18 @@ public PainlessLookup build() { } // precompute runtime classes - for (PainlessClassBuilder painlessStruct : painlessTypesToPainlessClasses.values()) { + for (PainlessClassBuilder painlessStruct : classesToPainlessClasses.values()) { addRuntimeClass(painlessStruct); } Map, PainlessClass> javaClassesToPainlessClasses = new HashMap<>(); // copy all structs to make them unmodifiable for outside users: - for (Map.Entry,PainlessClassBuilder> entry : painlessTypesToPainlessClasses.entrySet()) { + for (Map.Entry,PainlessClassBuilder> entry : classesToPainlessClasses.entrySet()) { entry.getValue().functionalMethod = computeFunctionalInterfaceMethod(entry.getValue()); javaClassesToPainlessClasses.put(entry.getKey(), entry.getValue().build()); } - return new PainlessLookup(painlessTypeNamesToPainlessTypes, javaClassesToPainlessClasses); + return new PainlessLookup(canonicalTypeNamesToClasses, javaClassesToPainlessClasses); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java index 726c2e647c610..f947341b6c50f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java @@ -31,138 +31,149 @@ * methods. * * The following terminology is used for variable names throughout the lookup package: + *
    + *
  • - javaClassName (String) - the fully qualified java class name where '$' tokens represent inner classes excluding + * def and array types
  • * - * - javaTypeName (String) - the fully qualified java type name for a painless type - * where '$' tokens are used to represent inner classes - * - painlessTypeName (String) - the fully qualified painless type name or imported painless - * type name for a painless type where '.' tokens replace '$' tokens - * - painlessType (Class) - a painless type represented by a java class including def - * and including array type java classes - * - painlessClass (PainlessClass) - a painless class object + *
  • - javaClass (Class) - a java class excluding def and array types
  • + * + *
  • - javaType (Class) - a java class excluding def and including array types
  • + * + *
  • - canonicalClassName (String) - the fully qualified painless class name equivalent to the fully + * qualified java canonical class name or imported painless type name for a type + * including def and excluding array types where '.' tokens represent inner classes
  • + * + *
  • - canonicalTypeName (String) - the fully qualified painless type name equivalent to the fully + * qualified java canonical type name or imported painless type name for a type + * including def where '.' tokens represent inner classes and each set of '[]' tokens + * at the end of the type name represent a single dimension for an array type
  • + * + *
  • - class/clazz (Class) - a painless class represented by a java class including def and excluding array + * types
  • + * + *
  • - type (Class) - a painless type represented by a java class including def and array types
  • + * + *
  • - painlessClass (PainlessClass) - a painless class object
  • + * + *
  • - painlessMethod (PainlessMethod) - a painless method object
  • + * + *
  • - painlessField (PainlessField) - a painless field object
  • + *
* * Under ambiguous circumstances most variable names are prefixed with asm, java, or painless. * If the variable value is the same for asm, java, and painless, no prefix is used. */ public final class PainlessLookupUtility { - public static String javaTypeNameToPainlessTypeName(String javaTypeName) { - Objects.requireNonNull(javaTypeName); - assert(javaTypeName.startsWith("[") == false); - - if (javaTypeName.startsWith(def.class.getName())) { - return javaTypeName.replace(def.class.getName(), DEF_PAINLESS_TYPE_NAME).replace('$', '.'); - } else { - return javaTypeName.replace('$', '.'); - } - } + public static Class canonicalTypeNameToType(String canonicalTypeName, Map> canonicalClassNamesToClasses) { + Objects.requireNonNull(canonicalTypeName); + Objects.requireNonNull(canonicalClassNamesToClasses); - public static Class painlessTypeNameToPainlessType(String painlessTypeName, Map> painlessTypeNamesToPainlessTypes) { - Objects.requireNonNull(painlessTypeName); - Objects.requireNonNull(painlessTypeNamesToPainlessTypes); + Class type = canonicalClassNamesToClasses.get(canonicalTypeName); - Class painlessType = painlessTypeNamesToPainlessTypes.get(painlessTypeName); - - if (painlessType != null) { - return painlessType; + if (type != null) { + return type; } int arrayDimensions = 0; - int arrayIndex = painlessTypeName.indexOf('['); + int arrayIndex = canonicalTypeName.indexOf('['); if (arrayIndex != -1) { - int painlessTypeNameLength = painlessTypeName.length(); + int typeNameLength = canonicalTypeName.length(); - while (arrayIndex < painlessTypeNameLength) { - if (painlessTypeName.charAt(arrayIndex) == '[' && - ++arrayIndex < painlessTypeNameLength && - painlessTypeName.charAt(arrayIndex++) == ']') { + while (arrayIndex < typeNameLength) { + if (canonicalTypeName.charAt(arrayIndex) == '[' && + ++arrayIndex < typeNameLength && + canonicalTypeName.charAt(arrayIndex++) == ']') { ++arrayDimensions; } else { - throw new IllegalArgumentException("painless type [" + painlessTypeName + "] not found"); + throw new IllegalArgumentException("type [" + canonicalTypeName + "] not found"); } } - painlessTypeName = painlessTypeName.substring(0, painlessTypeName.indexOf('[')); - painlessType = painlessTypeNamesToPainlessTypes.get(painlessTypeName); - - char javaDescriptorBraces[] = new char[arrayDimensions]; - Arrays.fill(javaDescriptorBraces, '['); - String javaDescriptor = new String(javaDescriptorBraces); - - if (painlessType == boolean.class) { - javaDescriptor += "Z"; - } else if (painlessType == byte.class) { - javaDescriptor += "B"; - } else if (painlessType == short.class) { - javaDescriptor += "S"; - } else if (painlessType == char.class) { - javaDescriptor += "C"; - } else if (painlessType == int.class) { - javaDescriptor += "I"; - } else if (painlessType == long.class) { - javaDescriptor += "J"; - } else if (painlessType == float.class) { - javaDescriptor += "F"; - } else if (painlessType == double.class) { - javaDescriptor += "D"; + canonicalTypeName = canonicalTypeName.substring(0, canonicalTypeName.indexOf('[')); + type = canonicalClassNamesToClasses.get(canonicalTypeName); + + char arrayBraces[] = new char[arrayDimensions]; + Arrays.fill(arrayBraces, '['); + String javaTypeName = new String(arrayBraces); + + if (type == boolean.class) { + javaTypeName += "Z"; + } else if (type == byte.class) { + javaTypeName += "B"; + } else if (type == short.class) { + javaTypeName += "S"; + } else if (type == char.class) { + javaTypeName += "C"; + } else if (type == int.class) { + javaTypeName += "I"; + } else if (type == long.class) { + javaTypeName += "J"; + } else if (type == float.class) { + javaTypeName += "F"; + } else if (type == double.class) { + javaTypeName += "D"; } else { - javaDescriptor += "L" + painlessType.getName() + ";"; + javaTypeName += "L" + type.getName() + ";"; } try { - return Class.forName(javaDescriptor); + return Class.forName(javaTypeName); } catch (ClassNotFoundException cnfe) { - throw new IllegalArgumentException("painless type [" + painlessTypeName + "] not found", cnfe); + throw new IllegalArgumentException("type [" + canonicalTypeName + "] not found", cnfe); } } - throw new IllegalArgumentException("painless type [" + painlessTypeName + "] not found"); + throw new IllegalArgumentException("type [" + canonicalTypeName + "] not found"); } - public static String painlessTypeToPainlessTypeName(Class painlessType) { - Objects.requireNonNull(painlessType); + public static String typeToCanonicalTypeName(Class type) { + Objects.requireNonNull(type); + + String canonicalTypeName = type.getCanonicalName(); - if (painlessType.getCanonicalName().startsWith(def.class.getName())) { - return painlessType.getCanonicalName().replace(def.class.getName(), DEF_PAINLESS_TYPE_NAME).replace('$', '.'); - } else { - return painlessType.getCanonicalName().replace('$', '.'); + if (canonicalTypeName.startsWith(def.class.getName())) { + canonicalTypeName = canonicalTypeName.replace(def.class.getName(), DEF_TYPE_NAME); } + + return canonicalTypeName; } - public static String painlessTypesToPainlessTypeNames(List> painlessTypes) { - StringBuilder painlessTypesStringBuilder = new StringBuilder("["); + public static String typesToCanonicalTypeNames(List> types) { + StringBuilder typesStringBuilder = new StringBuilder("["); - int anyTypesSize = painlessTypes.size(); + int anyTypesSize = types.size(); int anyTypesIndex = 0; - for (Class painlessType : painlessTypes) { - String anyTypeCanonicalName = javaTypeNameToPainlessTypeName(painlessType.getCanonicalName()); + for (Class painlessType : types) { + String canonicalTypeName = typeToCanonicalTypeName(painlessType); - painlessTypesStringBuilder.append(anyTypeCanonicalName); + typesStringBuilder.append(canonicalTypeName); if (++anyTypesIndex < anyTypesSize) { - painlessTypesStringBuilder.append(","); + typesStringBuilder.append(","); } } - painlessTypesStringBuilder.append("]"); + typesStringBuilder.append("]"); - return painlessTypesStringBuilder.toString(); + return typesStringBuilder.toString(); } - public static Class ObjectTypeTodefType(Class painlessType) { - Objects.requireNonNull(painlessType); + public static Class javaTypeToType(Class javaType) { + Objects.requireNonNull(javaType); - if (painlessType.isArray()) { - Class painlessTypeComponent = painlessType.getComponentType(); + if (javaType.isArray()) { + Class javaTypeComponent = javaType.getComponentType(); int arrayDimensions = 1; - while (painlessTypeComponent.isArray()) { - painlessTypeComponent = painlessTypeComponent.getComponentType(); + while (javaTypeComponent.isArray()) { + javaTypeComponent = javaTypeComponent.getComponentType(); ++arrayDimensions; } - if (painlessTypeComponent == Object.class) { + if (javaTypeComponent == Object.class) { char[] arrayBraces = new char[arrayDimensions]; Arrays.fill(arrayBraces, '['); @@ -172,26 +183,26 @@ public static Class ObjectTypeTodefType(Class painlessType) { throw new IllegalStateException("internal error", cnfe); } } - } else if (painlessType == Object.class) { + } else if (javaType == Object.class) { return def.class; } - return painlessType; + return javaType; } - public static Class defTypeToObjectType(Class painlessType) { - Objects.requireNonNull(painlessType); + public static Class typeToJavaType(Class type) { + Objects.requireNonNull(type); - if (painlessType.isArray()) { - Class painlessTypeComponent = painlessType.getComponentType(); + if (type.isArray()) { + Class typeComponent = type.getComponentType(); int arrayDimensions = 1; - while (painlessTypeComponent.isArray()) { - painlessTypeComponent = painlessTypeComponent.getComponentType(); + while (typeComponent.isArray()) { + typeComponent = typeComponent.getComponentType(); ++arrayDimensions; } - if (painlessTypeComponent == def.class) { + if (typeComponent == def.class) { char[] arrayBraces = new char[arrayDimensions]; Arrays.fill(arrayBraces, '['); @@ -201,79 +212,79 @@ public static Class defTypeToObjectType(Class painlessType) { throw new IllegalStateException("internal error", cnfe); } } - } else if (painlessType == def.class) { + } else if (type == def.class) { return Object.class; } - return painlessType; + return type; } - public static void validatePainlessType(Class painlessType, Collection> painlessTypes) { - String painlessTypeName = javaTypeNameToPainlessTypeName(painlessType.getCanonicalName()); + public static void validateType(Class type, Collection> classes) { + String canonicalTypeName = typeToCanonicalTypeName(type); - while (painlessType.getComponentType() != null) { - painlessType = painlessType.getComponentType(); + while (type.getComponentType() != null) { + type = type.getComponentType(); } - if (painlessTypes.contains(painlessType) == false) { - throw new IllegalArgumentException("painless type [" + painlessTypeName + "] not found"); + if (classes.contains(type) == false) { + throw new IllegalArgumentException("type [" + canonicalTypeName + "] not found"); } } - public static Class toBoxedPainlessType(Class painlessType) { - if (painlessType == boolean.class) { + public static Class typeToBoxedType(Class type) { + if (type == boolean.class) { return Boolean.class; - } else if (painlessType == byte.class) { + } else if (type == byte.class) { return Byte.class; - } else if (painlessType == short.class) { + } else if (type == short.class) { return Short.class; - } else if (painlessType == char.class) { + } else if (type == char.class) { return Character.class; - } else if (painlessType == int.class) { + } else if (type == int.class) { return Integer.class; - } else if (painlessType == long.class) { + } else if (type == long.class) { return Long.class; - } else if (painlessType == float.class) { + } else if (type == float.class) { return Float.class; - } else if (painlessType == double.class) { + } else if (type == double.class) { return Double.class; } - return painlessType; + return type; } - public static Class toUnboxedPainlessType(Class painlessType) { - if (painlessType == Boolean.class) { + public static Class typeToUnboxedType(Class type) { + if (type == Boolean.class) { return boolean.class; - } else if (painlessType == Byte.class) { + } else if (type == Byte.class) { return byte.class; - } else if (painlessType == Short.class) { + } else if (type == Short.class) { return short.class; - } else if (painlessType == Character.class) { + } else if (type == Character.class) { return char.class; - } else if (painlessType == Integer.class) { + } else if (type == Integer.class) { return int.class; - } else if (painlessType == Long.class) { + } else if (type == Long.class) { return long.class; - } else if (painlessType == Float.class) { + } else if (type == Float.class) { return float.class; - } else if (painlessType == Double.class) { + } else if (type == Double.class) { return double.class; } - return painlessType; + return type; } - public static boolean isConstantPainlessType(Class painlessType) { - return painlessType == boolean.class || - painlessType == byte.class || - painlessType == short.class || - painlessType == char.class || - painlessType == int.class || - painlessType == long.class || - painlessType == float.class || - painlessType == double.class || - painlessType == String.class; + public static boolean isConstantType(Class type) { + return type == boolean.class || + type == byte.class || + type == short.class || + type == char.class || + type == int.class || + type == long.class || + type == float.class || + type == double.class || + type == String.class; } public static String buildPainlessMethodKey(String methodName, int methodArity) { @@ -284,8 +295,8 @@ public static String buildPainlessFieldKey(String fieldName) { return fieldName; } - public static final String DEF_PAINLESS_TYPE_NAME = "def"; - public static final String CONSTRUCTOR_ANY_NAME = ""; + public static final String DEF_TYPE_NAME = "def"; + public static final String CONSTRUCTOR_NAME = ""; private PainlessLookupUtility() { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessMethod.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessMethod.java index fd63daf4eff2a..3321de94a267f 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessMethod.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessMethod.java @@ -70,21 +70,21 @@ public MethodType getMethodType() { params = new Class[1 + arguments.size()]; params[0] = augmentation; for (int i = 0; i < arguments.size(); i++) { - params[i + 1] = PainlessLookupUtility.defTypeToObjectType(arguments.get(i)); + params[i + 1] = PainlessLookupUtility.typeToJavaType(arguments.get(i)); } - returnValue = PainlessLookupUtility.defTypeToObjectType(rtn); + returnValue = PainlessLookupUtility.typeToJavaType(rtn); } else if (Modifier.isStatic(modifiers)) { // static method: straightforward copy params = new Class[arguments.size()]; for (int i = 0; i < arguments.size(); i++) { - params[i] = PainlessLookupUtility.defTypeToObjectType(arguments.get(i)); + params[i] = PainlessLookupUtility.typeToJavaType(arguments.get(i)); } - returnValue = PainlessLookupUtility.defTypeToObjectType(rtn); + returnValue = PainlessLookupUtility.typeToJavaType(rtn); } else if ("".equals(name)) { // constructor: returns the owner class params = new Class[arguments.size()]; for (int i = 0; i < arguments.size(); i++) { - params[i] = PainlessLookupUtility.defTypeToObjectType(arguments.get(i)); + params[i] = PainlessLookupUtility.typeToJavaType(arguments.get(i)); } returnValue = target; } else { @@ -92,9 +92,9 @@ public MethodType getMethodType() { params = new Class[1 + arguments.size()]; params[0] = target; for (int i = 0; i < arguments.size(); i++) { - params[i + 1] = PainlessLookupUtility.defTypeToObjectType(arguments.get(i)); + params[i + 1] = PainlessLookupUtility.typeToJavaType(arguments.get(i)); } - returnValue = PainlessLookupUtility.defTypeToObjectType(rtn); + returnValue = PainlessLookupUtility.typeToJavaType(rtn); } return MethodType.methodType(returnValue, params); } 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 1c6c0ef10db97..ddf289564b130 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 @@ -157,7 +157,7 @@ AExpression cast(Locals locals) { return ecast; } else { - if (PainlessLookupUtility.isConstantPainlessType(expected)) { + if (PainlessLookupUtility.isConstantType(expected)) { // For the case where a cast is required, a constant is set, // and the constant can be immediately cast to the expected type. // An EConstant replaces this node with the constant cast appropriately 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 1a5b6a9cf37f1..00abe788bf46d 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 @@ -106,8 +106,8 @@ private void analyzeMul(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply multiply [*] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } actual = promote; @@ -149,8 +149,8 @@ private void analyzeDiv(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply divide [/] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } actual = promote; @@ -197,8 +197,8 @@ private void analyzeRem(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply remainder [%] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } actual = promote; @@ -245,8 +245,8 @@ private void analyzeAdd(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply add [+] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } actual = promote; @@ -304,8 +304,8 @@ private void analyzeSub(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply subtract [-] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } actual = promote; @@ -363,8 +363,8 @@ private void analyzeLSH(Locals variables) { if (lhspromote == null || rhspromote == null) { throw createError(new ClassCastException("Cannot apply left shift [<<] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } actual = promote = lhspromote; @@ -411,8 +411,8 @@ private void analyzeRSH(Locals variables) { if (lhspromote == null || rhspromote == null) { throw createError(new ClassCastException("Cannot apply right shift [>>] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } actual = promote = lhspromote; @@ -462,8 +462,8 @@ private void analyzeUSH(Locals variables) { if (lhspromote == null || rhspromote == null) { throw createError(new ClassCastException("Cannot apply unsigned shift [>>>] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } if (lhspromote == def.class || rhspromote == def.class) { @@ -506,8 +506,8 @@ private void analyzeBWAnd(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply and [&] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } actual = promote; @@ -546,8 +546,8 @@ private void analyzeXor(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply xor [^] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } actual = promote; @@ -587,8 +587,8 @@ private void analyzeBWOr(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply or [|] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } actual = promote; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECapturingFunctionRef.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECapturingFunctionRef.java index 3e7cbeab74986..7b35bc1b48ee5 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECapturingFunctionRef.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ECapturingFunctionRef.java @@ -69,7 +69,7 @@ void analyze(Locals locals) { defPointer = "D" + variable + "." + call + ",1"; } else { // typed implementation - defPointer = "S" + PainlessLookupUtility.painlessTypeToPainlessTypeName(captured.clazz) + "." + call + ",1"; + defPointer = "S" + PainlessLookupUtility.typeToCanonicalTypeName(captured.clazz) + "." + call + ",1"; } actual = String.class; } else { @@ -78,7 +78,7 @@ void analyze(Locals locals) { if (captured.clazz != def.class) { try { ref = new FunctionRef(locals.getPainlessLookup(), expected, - PainlessLookupUtility.painlessTypeToPainlessTypeName(captured.clazz), call, 1); + PainlessLookupUtility.typeToCanonicalTypeName(captured.clazz), call, 1); // check casts between the interface method and the delegate method are legal for (int i = 0; i < ref.interfaceMethod.arguments.size(); ++i) { @@ -110,7 +110,7 @@ void write(MethodWriter writer, Globals globals) { // typed interface, dynamic implementation writer.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot()); Type methodType = Type.getMethodType(MethodWriter.getType(expected), MethodWriter.getType(captured.clazz)); - writer.invokeDefCall(call, methodType, DefBootstrap.REFERENCE, PainlessLookupUtility.painlessTypeToPainlessTypeName(expected)); + writer.invokeDefCall(call, methodType, DefBootstrap.REFERENCE, PainlessLookupUtility.typeToCanonicalTypeName(expected)); } else { // typed interface, typed implementation writer.visitVarInsn(MethodWriter.getType(captured.clazz).getOpcode(Opcodes.ILOAD), captured.getSlot()); 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 7990e5b41aa7e..b07613714b8ef 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 @@ -63,6 +63,6 @@ void write(MethodWriter writer, Globals globals) { @Override public String toString() { - return singleLineToString(PainlessLookupUtility.painlessTypeToPainlessTypeName(cast.to), child); + return singleLineToString(PainlessLookupUtility.typeToCanonicalTypeName(cast.to), child); } } 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 7e09c20467235..4d8a71ae3eb14 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 @@ -93,8 +93,8 @@ private void analyzeEq(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply equals [==] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } if (promotedType == def.class) { @@ -143,8 +143,8 @@ private void analyzeEqR(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply reference equals [===] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } left.expected = promotedType; @@ -184,8 +184,8 @@ private void analyzeNE(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply not equals [!=] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } if (promotedType == def.class) { @@ -234,8 +234,8 @@ private void analyzeNER(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply reference not equals [!==] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } left.expected = promotedType; @@ -275,8 +275,8 @@ private void analyzeGTE(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply greater than or equals [>=] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } if (promotedType == def.class) { @@ -315,8 +315,8 @@ private void analyzeGT(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply greater than [>] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } if (promotedType == def.class) { @@ -355,8 +355,8 @@ private void analyzeLTE(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply less than or equals [<=] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } if (promotedType == def.class) { @@ -395,8 +395,8 @@ private void analyzeLT(Locals variables) { if (promotedType == null) { throw createError(new ClassCastException("Cannot apply less than [>=] to types " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(left.actual) + "] and " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(right.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(left.actual) + "] and " + + "[" + PainlessLookupUtility.typeToCanonicalTypeName(right.actual) + "].")); } if (promotedType == def.class) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EFunctionRef.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EFunctionRef.java index 1f2fda47ddcb8..d787db5d41c92 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EFunctionRef.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EFunctionRef.java @@ -68,13 +68,13 @@ void analyze(Locals locals) { PainlessMethod interfaceMethod = locals.getPainlessLookup().getPainlessStructFromJavaClass(expected).functionalMethod; if (interfaceMethod == null) { throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " + - "to [" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expected) + "], not a functional interface"); + "to [" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "], not a functional interface"); } PainlessMethod delegateMethod = locals.getMethod(PainlessLookupUtility.buildPainlessMethodKey(call, interfaceMethod.arguments.size())); if (delegateMethod == null) { throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " + - "to [" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expected) + "], function not found"); + "to [" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "], function not found"); } ref = new FunctionRef(expected, interfaceMethod, delegateMethod, 0); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java index 959fcb2ac059c..2fa8ca8ca9513 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EInstanceof.java @@ -64,8 +64,8 @@ void analyze(Locals locals) { } // map to wrapped type for primitive types - resolvedType = clazz.isPrimitive() ? PainlessLookupUtility.toBoxedPainlessType(clazz) : - PainlessLookupUtility.defTypeToObjectType(clazz); + resolvedType = clazz.isPrimitive() ? PainlessLookupUtility.typeToBoxedType(clazz) : + PainlessLookupUtility.typeToJavaType(clazz); // analyze and cast the expression expression.analyze(locals); @@ -76,7 +76,7 @@ void analyze(Locals locals) { primitiveExpression = expression.actual.isPrimitive(); // map to wrapped type for primitive types expressionType = expression.actual.isPrimitive() ? - PainlessLookupUtility.toBoxedPainlessType(expression.actual) : PainlessLookupUtility.defTypeToObjectType(clazz); + PainlessLookupUtility.typeToBoxedType(expression.actual) : PainlessLookupUtility.typeToJavaType(clazz); actual = boolean.class; } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ELambda.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ELambda.java index f8d38b0f20199..ab1442be805eb 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ELambda.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ELambda.java @@ -123,12 +123,12 @@ void analyze(Locals locals) { interfaceMethod = locals.getPainlessLookup().getPainlessStructFromJavaClass(expected).functionalMethod; if (interfaceMethod == null) { throw createError(new IllegalArgumentException("Cannot pass lambda to " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expected) + "], not a functional interface")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "], not a functional interface")); } // check arity before we manipulate parameters if (interfaceMethod.arguments.size() != paramTypeStrs.size()) throw new IllegalArgumentException("Incorrect number of parameters for [" + interfaceMethod.name + - "] in [" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expected) + "]"); + "] in [" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "]"); // for method invocation, its allowed to ignore the return value if (interfaceMethod.rtn == void.class) { returnType = def.class; @@ -140,7 +140,7 @@ void analyze(Locals locals) { for (int i = 0; i < paramTypeStrs.size(); i++) { String paramType = paramTypeStrs.get(i); if (paramType == null) { - actualParamTypeStrs.add(PainlessLookupUtility.painlessTypeToPainlessTypeName(interfaceMethod.arguments.get(i))); + actualParamTypeStrs.add(PainlessLookupUtility.typeToCanonicalTypeName(interfaceMethod.arguments.get(i))); } else { actualParamTypeStrs.add(paramType); } @@ -162,14 +162,14 @@ void analyze(Locals locals) { List paramTypes = new ArrayList<>(captures.size() + actualParamTypeStrs.size()); List paramNames = new ArrayList<>(captures.size() + paramNameStrs.size()); for (Variable var : captures) { - paramTypes.add(PainlessLookupUtility.painlessTypeToPainlessTypeName(var.clazz)); + paramTypes.add(PainlessLookupUtility.typeToCanonicalTypeName(var.clazz)); paramNames.add(var.name); } paramTypes.addAll(actualParamTypeStrs); paramNames.addAll(paramNameStrs); // desugar lambda body into a synthetic method - desugared = new SFunction(reserved, location, PainlessLookupUtility.painlessTypeToPainlessTypeName(returnType), name, + desugared = new SFunction(reserved, location, PainlessLookupUtility.typeToCanonicalTypeName(returnType), name, paramTypes, paramNames, statements, true); desugared.generateSignature(locals.getPainlessLookup()); desugared.analyze(Locals.newLambdaScope(locals.getProgramScope(), returnType, 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 de2a21ae3c509..3a47dfc725f29 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 @@ -53,7 +53,7 @@ void analyze(Locals locals) { if (expected != null) { if (expected.isPrimitive()) { throw createError(new IllegalArgumentException( - "Cannot cast null to a primitive type [" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expected) + "].")); + "Cannot cast null to a primitive type [" + PainlessLookupUtility.typeToCanonicalTypeName(expected) + "].")); } actual = expected; 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 78f2a5c4ee19b..1c0fce8187646 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 @@ -94,7 +94,7 @@ void analyzeBWNot(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply not [~] to type " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(child.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(child.actual) + "].")); } child.expected = promote; @@ -124,7 +124,7 @@ void analyzerAdd(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply positive [+] to type " + - "[" + PainlessLookupUtility.defTypeToObjectType(child.actual) + "].")); + "[" + PainlessLookupUtility.typeToJavaType(child.actual) + "].")); } child.expected = promote; @@ -158,7 +158,7 @@ void analyzerSub(Locals variables) { if (promote == null) { throw createError(new ClassCastException("Cannot apply negative [-] to type " + - "[" + PainlessLookupUtility.defTypeToObjectType(child.actual) + "].")); + "[" + PainlessLookupUtility.typeToJavaType(child.actual) + "].")); } child.expected = promote; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java index 40d1c8d577abc..7b55cb5a804a0 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PBrace.java @@ -68,7 +68,7 @@ void analyze(Locals locals) { sub = new PSubListShortcut(location, locals.getPainlessLookup().getPainlessStructFromJavaClass(prefix.actual), index); } else { throw createError(new IllegalArgumentException("Illegal array access on type " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(prefix.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(prefix.actual) + "].")); } sub.write = write; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java index 01063831c2d29..8fc8a612b845d 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PCallInvoke.java @@ -73,7 +73,7 @@ void analyze(Locals locals) { PainlessClass struct = locals.getPainlessLookup().getPainlessStructFromJavaClass(prefix.actual); if (prefix.actual.isPrimitive()) { - struct = locals.getPainlessLookup().getPainlessStructFromJavaClass(PainlessLookupUtility.toBoxedPainlessType(prefix.actual)); + struct = locals.getPainlessLookup().getPainlessStructFromJavaClass(PainlessLookupUtility.typeToBoxedType(prefix.actual)); } String methodKey = PainlessLookupUtility.buildPainlessMethodKey(name, arguments.size()); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java index a21bbcc5d2fe4..abf398d0e6725 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PField.java @@ -63,7 +63,7 @@ void analyze(Locals locals) { prefix = prefix.cast(locals); if (prefix.actual.isArray()) { - sub = new PSubArrayLength(location, PainlessLookupUtility.painlessTypeToPainlessTypeName(prefix.actual), value); + sub = new PSubArrayLength(location, PainlessLookupUtility.typeToCanonicalTypeName(prefix.actual), value); } else if (prefix.actual == def.class) { sub = new PSubDefField(location, value); } else { @@ -86,7 +86,7 @@ void analyze(Locals locals) { if (getter != null || setter != null) { sub = new PSubShortcut( - location, value, PainlessLookupUtility.painlessTypeToPainlessTypeName(prefix.actual), getter, setter); + location, value, PainlessLookupUtility.typeToCanonicalTypeName(prefix.actual), getter, setter); } else { EConstant index = new EConstant(location, value); index.analyze(locals); @@ -104,7 +104,7 @@ void analyze(Locals locals) { if (sub == null) { throw createError(new IllegalArgumentException( - "Unknown field [" + value + "] for type [" + PainlessLookupUtility.painlessTypeToPainlessTypeName(prefix.actual) + "].")); + "Unknown field [" + value + "] for type [" + PainlessLookupUtility.typeToCanonicalTypeName(prefix.actual) + "].")); } if (nullSafe) { diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubField.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubField.java index 4cb3d83666367..007a599e9f842 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubField.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubField.java @@ -53,7 +53,7 @@ void extractVariables(Set variables) { void analyze(Locals locals) { if (write && Modifier.isFinal(field.modifiers)) { throw createError(new IllegalArgumentException("Cannot write to read-only field [" + field.name + "] for type " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(field.clazz) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(field.clazz) + "].")); } actual = field.clazz; diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java index fb91b076574f5..9ff57e6b913cc 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SEach.java @@ -85,7 +85,7 @@ void analyze(Locals locals) { sub = new SSubEachIterable(location, variable, expression, block); } else { throw createError(new IllegalArgumentException("Illegal for each type " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expression.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(expression.actual) + "].")); } sub.analyze(locals); diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFunction.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFunction.java index 37978d884a6e7..7c243e296c7e3 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFunction.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SFunction.java @@ -136,7 +136,7 @@ void generateSignature(PainlessLookup painlessLookup) { try { Class paramType = painlessLookup.getJavaClassFromPainlessType(this.paramTypeStrs.get(param)); - paramClasses[param] = PainlessLookupUtility.defTypeToObjectType(paramType); + paramClasses[param] = PainlessLookupUtility.typeToJavaType(paramType); paramTypes.add(paramType); parameters.add(new Parameter(location, paramNameStrs.get(param), paramType)); } catch (IllegalArgumentException exception) { @@ -146,7 +146,7 @@ void generateSignature(PainlessLookup painlessLookup) { } org.objectweb.asm.commons.Method method = new org.objectweb.asm.commons.Method(name, MethodType.methodType( - PainlessLookupUtility.defTypeToObjectType(rtnType), paramClasses).toMethodDescriptorString()); + PainlessLookupUtility.typeToJavaType(rtnType), paramClasses).toMethodDescriptorString()); this.method = new PainlessMethod(name, null, null, rtnType, paramTypes, method, Modifier.STATIC | Modifier.PRIVATE, null); } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachArray.java index 655547a066287..7e0d74865f9c7 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachArray.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachArray.java @@ -109,6 +109,6 @@ void write(MethodWriter writer, Globals globals) { @Override public String toString() { - return singleLineToString(PainlessLookupUtility.painlessTypeToPainlessTypeName(variable.clazz), variable.name, expression, block); + return singleLineToString(PainlessLookupUtility.typeToCanonicalTypeName(variable.clazz), variable.name, expression, block); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachIterable.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachIterable.java index e02a2bfdf2b54..12e3154eb562e 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachIterable.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SSubEachIterable.java @@ -81,7 +81,7 @@ void analyze(Locals locals) { if (method == null) { throw createError(new IllegalArgumentException("Unable to create iterator for the type " + - "[" + PainlessLookupUtility.painlessTypeToPainlessTypeName(expression.actual) + "].")); + "[" + PainlessLookupUtility.typeToCanonicalTypeName(expression.actual) + "].")); } } @@ -132,6 +132,6 @@ void write(MethodWriter writer, Globals globals) { @Override public String toString() { - return singleLineToString(PainlessLookupUtility.painlessTypeToPainlessTypeName(variable.clazz), variable.name, expression, block); + return singleLineToString(PainlessLookupUtility.typeToCanonicalTypeName(variable.clazz), variable.name, expression, block); } } diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/PainlessDocGenerator.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/PainlessDocGenerator.java index 31473a554c6d8..e26a5a38c76b8 100644 --- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/PainlessDocGenerator.java +++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/PainlessDocGenerator.java @@ -210,7 +210,7 @@ private static void documentMethod(PrintStream stream, PainlessMethod method) { */ private static void emitAnchor(PrintStream stream, Class clazz) { stream.print("painless-api-reference-"); - stream.print(PainlessLookupUtility.painlessTypeToPainlessTypeName(clazz).replace('.', '-')); + stream.print(PainlessLookupUtility.typeToCanonicalTypeName(clazz).replace('.', '-')); } /** @@ -234,7 +234,7 @@ private static void emitAnchor(PrintStream stream, PainlessField field) { } private static String methodName(PainlessMethod method) { - return method.name.equals("") ? PainlessLookupUtility.painlessTypeToPainlessTypeName(method.target) : method.name; + return method.name.equals("") ? PainlessLookupUtility.typeToCanonicalTypeName(method.target) : method.name; } /** From b653921389651abaca25dcedd7078a75d08017a9 Mon Sep 17 00:00:00 2001 From: Jack Conradson Date: Thu, 19 Jul 2018 14:06:14 -0700 Subject: [PATCH 4/4] Response to PR comments. --- .../lookup/PainlessLookupBuilder.java | 30 ++++---- .../lookup/PainlessLookupUtility.java | 76 +++++++++++++++++-- 2 files changed, 83 insertions(+), 23 deletions(-) diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupBuilder.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupBuilder.java index 365a5b12a0d9c..06773d3ffddf9 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupBuilder.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupBuilder.java @@ -122,22 +122,22 @@ public int hashCode() { private final List whitelists; - private final Map> canonicalTypeNamesToClasses; + private final Map> canonicalClassNamesToClasses; private final Map, PainlessClassBuilder> classesToPainlessClasses; public PainlessLookupBuilder(List whitelists) { this.whitelists = whitelists; - canonicalTypeNamesToClasses = new HashMap<>(); + canonicalClassNamesToClasses = new HashMap<>(); classesToPainlessClasses = new HashMap<>(); - canonicalTypeNamesToClasses.put(DEF_TYPE_NAME, def.class); + canonicalClassNamesToClasses.put(DEF_TYPE_NAME, def.class); classesToPainlessClasses.put(def.class, new PainlessClassBuilder(DEF_TYPE_NAME, Object.class, Type.getType(Object.class))); } private Class canonicalTypeNameToType(String canonicalTypeName) { - return PainlessLookupUtility.canonicalTypeNameToType(canonicalTypeName, canonicalTypeNamesToClasses); + return PainlessLookupUtility.canonicalTypeNameToType(canonicalTypeName, canonicalClassNamesToClasses); } private void validateType(Class type) { @@ -192,7 +192,7 @@ public void addPainlessClass(Class clazz, boolean importClassName) { if (existingPainlessClassBuilder == null) { PainlessClassBuilder painlessClassBuilder = new PainlessClassBuilder(canonicalClassName, clazz, Type.getType(clazz)); - canonicalTypeNamesToClasses.put(canonicalClassName, clazz); + canonicalClassNamesToClasses.put(canonicalClassName, clazz); classesToPainlessClasses.put(clazz, painlessClassBuilder); } else if (existingPainlessClassBuilder.clazz.equals(clazz) == false) { throw new IllegalArgumentException("class [" + canonicalClassName + "] " + @@ -207,7 +207,7 @@ public void addPainlessClass(Class clazz, boolean importClassName) { throw new IllegalArgumentException("must use only_fqn parameter on class [" + canonicalClassName + "] with no package"); } } else { - Class importedPainlessType = canonicalTypeNamesToClasses.get(importedCanonicalClassName); + Class importedPainlessType = canonicalClassNamesToClasses.get(importedCanonicalClassName); if (importedPainlessType == null) { if (importClassName) { @@ -216,7 +216,7 @@ public void addPainlessClass(Class clazz, boolean importClassName) { "inconsistent only_fqn parameters found for painless type [" + canonicalClassName + "]"); } - canonicalTypeNamesToClasses.put(importedCanonicalClassName, clazz); + canonicalClassNamesToClasses.put(importedCanonicalClassName, clazz); } } else if (importedPainlessType.equals(clazz) == false) { throw new IllegalArgumentException("painless type [" + importedCanonicalClassName + "] illegally represents multiple " + @@ -228,7 +228,7 @@ public void addPainlessClass(Class clazz, boolean importClassName) { } private void addConstructor(String ownerStructName, WhitelistConstructor whitelistConstructor) { - PainlessClassBuilder ownerStruct = classesToPainlessClasses.get(canonicalTypeNamesToClasses.get(ownerStructName)); + PainlessClassBuilder ownerStruct = classesToPainlessClasses.get(canonicalClassNamesToClasses.get(ownerStructName)); if (ownerStruct == null) { throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for constructor with " + @@ -289,7 +289,7 @@ private void addConstructor(String ownerStructName, WhitelistConstructor whiteli } private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName, WhitelistMethod whitelistMethod) { - PainlessClassBuilder ownerStruct = classesToPainlessClasses.get(canonicalTypeNamesToClasses.get(ownerStructName)); + PainlessClassBuilder ownerStruct = classesToPainlessClasses.get(canonicalClassNamesToClasses.get(ownerStructName)); if (ownerStruct == null) { throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for method with " + @@ -427,7 +427,7 @@ private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName, } private void addField(String ownerStructName, WhitelistField whitelistField) { - PainlessClassBuilder ownerStruct = classesToPainlessClasses.get(canonicalTypeNamesToClasses.get(ownerStructName)); + PainlessClassBuilder ownerStruct = classesToPainlessClasses.get(canonicalClassNamesToClasses.get(ownerStructName)); if (ownerStruct == null) { throw new IllegalArgumentException("owner struct [" + ownerStructName + "] not defined for method with " + @@ -508,7 +508,7 @@ private void addField(String ownerStructName, WhitelistField whitelistField) { } private void copyStruct(String struct, List children) { - final PainlessClassBuilder owner = classesToPainlessClasses.get(canonicalTypeNamesToClasses.get(struct)); + final PainlessClassBuilder owner = classesToPainlessClasses.get(canonicalClassNamesToClasses.get(struct)); if (owner == null) { throw new IllegalArgumentException("Owner struct [" + struct + "] not defined for copy."); @@ -516,7 +516,7 @@ private void copyStruct(String struct, List children) { for (int count = 0; count < children.size(); ++count) { final PainlessClassBuilder child = - classesToPainlessClasses.get(canonicalTypeNamesToClasses.get(children.get(count))); + classesToPainlessClasses.get(canonicalClassNamesToClasses.get(children.get(count))); if (child == null) { throw new IllegalArgumentException("Child struct [" + children.get(count) + "]" + @@ -690,7 +690,7 @@ public PainlessLookup build() { for (WhitelistClass whitelistStruct : whitelist.whitelistStructs) { String painlessTypeName = whitelistStruct.javaClassName.replace('$', '.'); PainlessClassBuilder painlessStruct = - classesToPainlessClasses.get(canonicalTypeNamesToClasses.get(painlessTypeName)); + classesToPainlessClasses.get(canonicalClassNamesToClasses.get(painlessTypeName)); if (painlessStruct != null && painlessStruct.clazz.getName().equals(whitelistStruct.javaClassName) == false) { throw new IllegalArgumentException("struct [" + painlessStruct.name + "] cannot represent multiple classes " + @@ -701,7 +701,7 @@ public PainlessLookup build() { addPainlessClass( whitelist.javaClassLoader, whitelistStruct.javaClassName, whitelistStruct.onlyFQNJavaClassName == false); - painlessStruct = classesToPainlessClasses.get(canonicalTypeNamesToClasses.get(painlessTypeName)); + painlessStruct = classesToPainlessClasses.get(canonicalClassNamesToClasses.get(painlessTypeName)); classesToPainlessClasses.put(painlessStruct.clazz, painlessStruct); } } @@ -805,6 +805,6 @@ public PainlessLookup build() { javaClassesToPainlessClasses.put(entry.getKey(), entry.getValue().build()); } - return new PainlessLookup(canonicalTypeNamesToClasses, javaClassesToPainlessClasses); + return new PainlessLookup(canonicalClassNamesToClasses, javaClassesToPainlessClasses); } } diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java index f947341b6c50f..1f698b7c673f5 100644 --- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java +++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessLookupUtility.java @@ -26,11 +26,18 @@ import java.util.Objects; /** - * This class contains methods shared by {@link PainlessLookupBuilder}, {@link PainlessLookup}, and other - * classes within Painless for conversion between type names and types along with some other various utility - * methods. + * PainlessLookupUtility contains methods shared by {@link PainlessLookupBuilder}, {@link PainlessLookup}, and other classes within + * Painless for conversion between type names and types along with some other various utility methods. * * The following terminology is used for variable names throughout the lookup package: + * + * A class is a set of methods and fields under a specific class name. A type is either a class or an array under a specific type name. + * Note the distinction between class versus type is class means that no array classes will be be represented whereas type allows array + * classes to be represented. The set of available classes will always be a subset of the available types. + * + * Under ambiguous circumstances most variable names are prefixed with asm, java, or painless. If the variable value is the same for asm, + * java, and painless, no prefix is used. + * *
    *
  • - javaClassName (String) - the fully qualified java class name where '$' tokens represent inner classes excluding * def and array types
  • @@ -39,8 +46,11 @@ * *
  • - javaType (Class) - a java class excluding def and including array types
  • * + *
  • - importedClassName (String) - the imported painless class name where the java canonical class name is used without + * the package qualifier + * *
  • - canonicalClassName (String) - the fully qualified painless class name equivalent to the fully - * qualified java canonical class name or imported painless type name for a type + * qualified java canonical class name or imported painless class name for a class * including def and excluding array types where '.' tokens represent inner classes
  • * *
  • - canonicalTypeName (String) - the fully qualified painless type name equivalent to the fully @@ -59,12 +69,14 @@ * *
  • - painlessField (PainlessField) - a painless field object
  • *
- * - * Under ambiguous circumstances most variable names are prefixed with asm, java, or painless. - * If the variable value is the same for asm, java, and painless, no prefix is used. */ public final class PainlessLookupUtility { + /** + * Converts a canonical type name to a type based on the terminology specified as part of the documentation for + * {@link PainlessLookupUtility}. Since canonical class names are a subset of canonical type names, this method will + * safely convert a canonical class name to a class as well. + */ public static Class canonicalTypeNameToType(String canonicalTypeName, Map> canonicalClassNamesToClasses) { Objects.requireNonNull(canonicalTypeName); Objects.requireNonNull(canonicalClassNamesToClasses); @@ -128,6 +140,11 @@ public static Class canonicalTypeNameToType(String canonicalTypeName, Map type) { Objects.requireNonNull(type); @@ -140,6 +157,11 @@ public static String typeToCanonicalTypeName(Class type) { return canonicalTypeName; } + /** + * Converts a list of types to a list of canonical type names as a string based on the terminology specified as part of the + * documentation for {@link PainlessLookupUtility}. Since classes are a subset of types, this method will safely convert a list + * of classes or a mixed list of classes and types to a list of canonical type names as a string as well. + */ public static String typesToCanonicalTypeNames(List> types) { StringBuilder typesStringBuilder = new StringBuilder("["); @@ -160,7 +182,11 @@ public static String typesToCanonicalTypeNames(List> types) { return typesStringBuilder.toString(); } - + /** + * Converts a java type to a type based on the terminology specified as part of {@link PainlessLookupUtility} where if a type is an + * object class or object array, the returned type will be the equivalent def class or def array. Otherwise, this behaves as an + * identity function. + */ public static Class javaTypeToType(Class javaType) { Objects.requireNonNull(javaType); @@ -190,6 +216,11 @@ public static Class javaTypeToType(Class javaType) { return javaType; } + /** + * Converts a type to a java type based on the terminology specified as part of {@link PainlessLookupUtility} where if a type is a + * def class or def array, the returned type will be the equivalent object class or object array. Otherwise, this behaves as an + * identity function. + */ public static Class typeToJavaType(Class type) { Objects.requireNonNull(type); @@ -219,6 +250,10 @@ public static Class typeToJavaType(Class type) { return type; } + /** + * Ensures a type exists based on the terminology specified as part of {@link PainlessLookupUtility}. Throws an + * {@link IllegalArgumentException} if the type does not exist. + */ public static void validateType(Class type, Collection> classes) { String canonicalTypeName = typeToCanonicalTypeName(type); @@ -231,6 +266,10 @@ public static void validateType(Class type, Collection> classes) { } } + /** + * Converts a type to its boxed type equivalent if one exists based on the terminology specified as part of + * {@link PainlessLookupUtility}. Otherwise, this behaves as an identity function. + */ public static Class typeToBoxedType(Class type) { if (type == boolean.class) { return Boolean.class; @@ -253,6 +292,10 @@ public static Class typeToBoxedType(Class type) { return type; } + /** + * Converts a type to its unboxed type equivalent if one exists based on the terminology specified as part of + * {@link PainlessLookupUtility}. Otherwise, this behaves as an identity function. + */ public static Class typeToUnboxedType(Class type) { if (type == Boolean.class) { return boolean.class; @@ -275,6 +318,10 @@ public static Class typeToUnboxedType(Class type) { return type; } + /** + * Checks if a type based on the terminology specified as part of {@link PainlessLookupUtility} is available as a constant type + * where {@code true} is returned if the type is a constant type and {@code false} otherwise. + */ public static boolean isConstantType(Class type) { return type == boolean.class || type == byte.class || @@ -287,15 +334,28 @@ public static boolean isConstantType(Class type) { type == String.class; } + /** + * Constructs a painless method key used to lookup painless methods from a painless class. + */ public static String buildPainlessMethodKey(String methodName, int methodArity) { return methodName + "/" + methodArity; } + /** + * Constructs a painless field key used to lookup painless fields from a painless class. + */ public static String buildPainlessFieldKey(String fieldName) { return fieldName; } + /** + * The def type name as specified in the source for a script. + */ public static final String DEF_TYPE_NAME = "def"; + + /** + * The method name for all constructors. + */ public static final String CONSTRUCTOR_NAME = ""; private PainlessLookupUtility() {