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 4752c2b268573..1e17d6024d4d1 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
@@ -20,7 +20,6 @@
package org.elasticsearch.painless;
import org.elasticsearch.painless.Locals.LocalMethod;
-import org.elasticsearch.painless.lookup.PainlessClass;
import org.elasticsearch.painless.lookup.PainlessLookup;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.PainlessMethod;
@@ -38,6 +37,8 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import static org.elasticsearch.painless.lookup.PainlessLookupUtility.typeToCanonicalTypeName;
+
/**
* Support for dynamic type (def).
*
@@ -167,52 +168,6 @@ static MethodHandle arrayLengthGetter(Class> arrayType) {
}
}
- /**
- * Looks up method entry for a dynamic method call.
- *
- * A dynamic method call for variable {@code x} of type {@code def} looks like:
- * {@code x.method(args...)}
- *
- * This method traverses {@code recieverClass}'s class hierarchy (including interfaces)
- * until it finds a matching whitelisted method. If one is not found, it throws an exception.
- * Otherwise it returns the matching method.
- *
- * @params painlessLookup the whitelist
- * @param receiverClass Class of the object to invoke the method on.
- * @param name Name of the method.
- * @param arity arity of method
- * @return matching method to invoke. never returns null.
- * @throws IllegalArgumentException if no matching whitelisted method was found.
- */
- static PainlessMethod lookupMethodInternal(PainlessLookup painlessLookup, Class> receiverClass, String name, int arity) {
- String key = PainlessLookupUtility.buildPainlessMethodKey(name, arity);
- // check whitelist for matching method
- for (Class> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
- PainlessClass struct = painlessLookup.lookupPainlessClass(clazz);
-
- if (struct != null) {
- PainlessMethod method = struct.methods.get(key);
- if (method != null) {
- return method;
- }
- }
-
- for (Class> iface : clazz.getInterfaces()) {
- struct = painlessLookup.lookupPainlessClass(iface);
-
- if (struct != null) {
- PainlessMethod method = struct.methods.get(key);
- if (method != null) {
- return method;
- }
- }
- }
- }
-
- throw new IllegalArgumentException("Unable to find dynamic method [" + name + "] with [" + arity + "] arguments " +
- "for class [" + receiverClass.getCanonicalName() + "].");
- }
-
/**
* Looks up handle for a dynamic method call, with lambda replacement
*
@@ -241,7 +196,14 @@ static MethodHandle lookupMethod(PainlessLookup painlessLookup, Map localMethods,
MethodHandles.Lookup methodHandlesLookup, String interfaceClass, Class> receiverClass, String name) throws Throwable {
Class> interfaceType = painlessLookup.canonicalTypeNameToType(interfaceClass);
+ if (interfaceType == null) {
+ throw new IllegalArgumentException("type [" + interfaceClass + "] not found");
+ }
PainlessMethod interfaceMethod = painlessLookup.lookupFunctionalInterfacePainlessMethod(interfaceType);
if (interfaceMethod == null) {
throw new IllegalArgumentException("Class [" + interfaceClass + "] is not a functional interface");
}
int arity = interfaceMethod.typeParameters.size();
- PainlessMethod implMethod = lookupMethodInternal(painlessLookup, receiverClass, name, arity);
+ PainlessMethod implMethod = painlessLookup.lookupRuntimePainlessMethod(receiverClass, name, arity);
+ if (implMethod == null) {
+ throw new IllegalArgumentException(
+ "dynamic method [" + typeToCanonicalTypeName(receiverClass) + ", " + name + "/" + arity + "] not found");
+ }
+
return lookupReferenceInternal(painlessLookup, localMethods, methodHandlesLookup,
- interfaceType, PainlessLookupUtility.typeToCanonicalTypeName(implMethod.targetClass),
- implMethod.javaMethod.getName(), 1);
+ interfaceType, PainlessLookupUtility.typeToCanonicalTypeName(implMethod.targetClass),
+ implMethod.javaMethod.getName(), 1);
}
/** Returns a method handle to an implementation of clazz, given method reference signature. */
@@ -389,27 +365,12 @@ private static MethodHandle lookupReferenceInternal(PainlessLookup painlessLooku
*/
static MethodHandle lookupGetter(PainlessLookup painlessLookup, Class> receiverClass, String name) {
// first try whitelist
- for (Class> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
- PainlessClass struct = painlessLookup.lookupPainlessClass(clazz);
-
- if (struct != null) {
- MethodHandle handle = struct.getterMethodHandles.get(name);
- if (handle != null) {
- return handle;
- }
- }
-
- for (final Class> iface : clazz.getInterfaces()) {
- struct = painlessLookup.lookupPainlessClass(iface);
+ MethodHandle getter = painlessLookup.lookupRuntimeGetterMethodHandle(receiverClass, name);
- if (struct != null) {
- MethodHandle handle = struct.getterMethodHandles.get(name);
- if (handle != null) {
- return handle;
- }
- }
- }
+ if (getter != null) {
+ return getter;
}
+
// special case: arrays, maps, and lists
if (receiverClass.isArray() && "length".equals(name)) {
// arrays expose .length as a read-only getter
@@ -426,12 +387,12 @@ static MethodHandle lookupGetter(PainlessLookup painlessLookup, Class> receive
int index = Integer.parseInt(name);
return MethodHandles.insertArguments(LIST_GET, 1, index);
} catch (NumberFormatException exception) {
- throw new IllegalArgumentException( "Illegal list shortcut value [" + name + "].");
+ throw new IllegalArgumentException("Illegal list shortcut value [" + name + "].");
}
}
- throw new IllegalArgumentException("Unable to find dynamic field [" + name + "] " +
- "for class [" + receiverClass.getCanonicalName() + "].");
+ throw new IllegalArgumentException(
+ "dynamic getter [" + typeToCanonicalTypeName(receiverClass) + ", " + name + "] not found");
}
/**
@@ -460,27 +421,12 @@ static MethodHandle lookupGetter(PainlessLookup painlessLookup, Class> receive
*/
static MethodHandle lookupSetter(PainlessLookup painlessLookup, Class> receiverClass, String name) {
// first try whitelist
- for (Class> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
- PainlessClass struct = painlessLookup.lookupPainlessClass(clazz);
-
- if (struct != null) {
- MethodHandle handle = struct.setterMethodHandles.get(name);
- if (handle != null) {
- return handle;
- }
- }
-
- for (final Class> iface : clazz.getInterfaces()) {
- struct = painlessLookup.lookupPainlessClass(iface);
+ MethodHandle setter = painlessLookup.lookupRuntimeSetterMethodHandle(receiverClass, name);
- if (struct != null) {
- MethodHandle handle = struct.setterMethodHandles.get(name);
- if (handle != null) {
- return handle;
- }
- }
- }
+ if (setter != null) {
+ return setter;
}
+
// special case: maps, and lists
if (Map.class.isAssignableFrom(receiverClass)) {
// maps allow access like mymap.key
@@ -494,12 +440,12 @@ static MethodHandle lookupSetter(PainlessLookup painlessLookup, Class> receive
int index = Integer.parseInt(name);
return MethodHandles.insertArguments(LIST_SET, 1, index);
} catch (final NumberFormatException exception) {
- throw new IllegalArgumentException( "Illegal list shortcut value [" + name + "].");
+ throw new IllegalArgumentException("Illegal list shortcut value [" + name + "].");
}
}
- throw new IllegalArgumentException("Unable to find dynamic field [" + name + "] " +
- "for class [" + receiverClass.getCanonicalName() + "].");
+ throw new IllegalArgumentException(
+ "dynamic getter [" + typeToCanonicalTypeName(receiverClass) + ", " + name + "] not found");
}
/**
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 065f63dc3f5a4..2580d7da3e8e7 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
@@ -67,11 +67,11 @@ public static FunctionRef create(PainlessLookup painlessLookup, Map targetClass = canonicalTypeNameToType(targetClassName);
+ if (targetClass == null) {
+ return null;
+ }
+
return lookupPainlessConstructor(targetClass, constructorArity);
}
@@ -77,15 +83,13 @@ public PainlessConstructor lookupPainlessConstructor(Class> targetClass, int c
String painlessConstructorKey = buildPainlessConstructorKey(constructorArity);
if (targetPainlessClass == null) {
- throw new IllegalArgumentException("target class [" + typeToCanonicalTypeName(targetClass) + "] " +
- "not found for constructor [" + painlessConstructorKey + "]");
+ return null;
}
PainlessConstructor painlessConstructor = targetPainlessClass.constructors.get(painlessConstructorKey);
if (painlessConstructor == null) {
- throw new IllegalArgumentException(
- "constructor [" + typeToCanonicalTypeName(targetClass) + ", " + painlessConstructorKey + "] not found");
+ return null;
}
return painlessConstructor;
@@ -96,6 +100,10 @@ public PainlessMethod lookupPainlessMethod(String targetClassName, boolean isSta
Class> targetClass = canonicalTypeNameToType(targetClassName);
+ if (targetClass == null) {
+ return null;
+ }
+
return lookupPainlessMethod(targetClass, isStatic, methodName, methodArity);
}
@@ -104,27 +112,19 @@ public PainlessMethod lookupPainlessMethod(Class> targetClass, boolean isStati
Objects.requireNonNull(methodName);
if (targetClass.isPrimitive()) {
- targetClass = PainlessLookupUtility.typeToBoxedType(targetClass);
+ targetClass = typeToBoxedType(targetClass);
}
PainlessClass targetPainlessClass = classesToPainlessClasses.get(targetClass);
String painlessMethodKey = buildPainlessMethodKey(methodName, methodArity);
if (targetPainlessClass == null) {
- throw new IllegalArgumentException(
- "target class [" + typeToCanonicalTypeName(targetClass) + "] not found for method [" + painlessMethodKey + "]");
+ return null;
}
- PainlessMethod painlessMethod = isStatic ?
+ return isStatic ?
targetPainlessClass.staticMethods.get(painlessMethodKey) :
targetPainlessClass.methods.get(painlessMethodKey);
-
- if (painlessMethod == null) {
- throw new IllegalArgumentException(
- "method [" + typeToCanonicalTypeName(targetClass) + ", " + painlessMethodKey + "] not found");
- }
-
- return painlessMethod;
}
public PainlessField lookupPainlessField(String targetClassName, boolean isStatic, String fieldName) {
@@ -132,6 +132,10 @@ public PainlessField lookupPainlessField(String targetClassName, boolean isStati
Class> targetClass = canonicalTypeNameToType(targetClassName);
+ if (targetClass == null) {
+ return null;
+ }
+
return lookupPainlessField(targetClass, isStatic, fieldName);
}
@@ -143,8 +147,7 @@ public PainlessField lookupPainlessField(Class> targetClass, boolean isStatic,
String painlessFieldKey = buildPainlessFieldKey(fieldName);
if (targetPainlessClass == null) {
- throw new IllegalArgumentException(
- "target class [" + typeToCanonicalTypeName(targetClass) + "] not found for field [" + painlessFieldKey + "]");
+ return null;
}
PainlessField painlessField = isStatic ?
@@ -152,8 +155,7 @@ public PainlessField lookupPainlessField(Class> targetClass, boolean isStatic,
targetPainlessClass.fields.get(painlessFieldKey);
if (painlessField == null) {
- throw new IllegalArgumentException(
- "field [" + typeToCanonicalTypeName(targetClass) + ", " + painlessFieldKey + "] not found");
+ return null;
}
return painlessField;
@@ -163,15 +165,77 @@ public PainlessMethod lookupFunctionalInterfacePainlessMethod(Class> targetCla
PainlessClass targetPainlessClass = classesToPainlessClasses.get(targetClass);
if (targetPainlessClass == null) {
- throw new IllegalArgumentException("target class [" + typeToCanonicalTypeName(targetClass) + "] not found");
+ return null;
}
- PainlessMethod functionalInterfacePainlessMethod = targetPainlessClass.functionalInterfaceMethod;
+ return targetPainlessClass.functionalInterfaceMethod;
+ }
+
+ public PainlessMethod lookupRuntimePainlessMethod(Class> originalTargetClass, String methodName, int methodArity) {
+ Objects.requireNonNull(originalTargetClass);
+ Objects.requireNonNull(methodName);
+
+ String painlessMethodKey = buildPainlessMethodKey(methodName, methodArity);
+ Function objectLookup = targetPainlessClass -> targetPainlessClass.methods.get(painlessMethodKey);
+
+ return lookupRuntimePainlessObject(originalTargetClass, objectLookup);
+ }
+
+ public MethodHandle lookupRuntimeGetterMethodHandle(Class> originalTargetClass, String getterName) {
+ Objects.requireNonNull(originalTargetClass);
+ Objects.requireNonNull(getterName);
+
+ Function objectLookup = targetPainlessClass -> targetPainlessClass.getterMethodHandles.get(getterName);
+
+ return lookupRuntimePainlessObject(originalTargetClass, objectLookup);
+ }
+
+ public MethodHandle lookupRuntimeSetterMethodHandle(Class> originalTargetClass, String setterName) {
+ Objects.requireNonNull(originalTargetClass);
+ Objects.requireNonNull(setterName);
+
+ Function objectLookup = targetPainlessClass -> targetPainlessClass.setterMethodHandles.get(setterName);
+
+ return lookupRuntimePainlessObject(originalTargetClass, objectLookup);
+ }
+
+ private T lookupRuntimePainlessObject(
+ Class> originalTargetClass, Function objectLookup) {
+
+ Class> currentTargetClass = originalTargetClass;
+
+ while (currentTargetClass != null) {
+ PainlessClass targetPainlessClass = classesToPainlessClasses.get(currentTargetClass);
+
+ if (targetPainlessClass != null) {
+ T painlessObject = objectLookup.apply(targetPainlessClass);
+
+ if (painlessObject != null) {
+ return painlessObject;
+ }
+ }
+
+ currentTargetClass = currentTargetClass.getSuperclass();
+ }
+
+ currentTargetClass = originalTargetClass;
+
+ while (currentTargetClass != null) {
+ for (Class> targetInterface : currentTargetClass.getInterfaces()) {
+ PainlessClass targetPainlessClass = classesToPainlessClasses.get(targetInterface);
+
+ if (targetPainlessClass != null) {
+ T painlessObject = objectLookup.apply(targetPainlessClass);
+
+ if (painlessObject != null) {
+ return painlessObject;
+ }
+ }
+ }
- if (functionalInterfacePainlessMethod == null) {
- throw new IllegalArgumentException("target class [" + typeToCanonicalTypeName(targetClass) + "] is not a functional interface");
+ currentTargetClass = currentTargetClass.getSuperclass();
}
- return functionalInterfacePainlessMethod;
+ return null;
}
}
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 45a5e188db331..e17a01941bc97 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
@@ -220,8 +220,12 @@ private Class> canonicalTypeNameToType(String canonicalTypeName) {
return PainlessLookupUtility.canonicalTypeNameToType(canonicalTypeName, canonicalClassNamesToClasses);
}
- private void validateType(Class> type) {
- PainlessLookupUtility.validateType(type, classesToPainlessClassBuilders.keySet());
+ private boolean isValidType(Class> type) {
+ while (type.getComponentType() != null) {
+ type = type.getComponentType();
+ }
+
+ return classesToPainlessClassBuilders.containsKey(type);
}
public void addPainlessClass(ClassLoader classLoader, String javaClassName, boolean importClassName) {
@@ -325,13 +329,14 @@ public void addPainlessConstructor(String targetCanonicalClassName, List
List> typeParameters = new ArrayList<>(typeNameParameters.size());
for (String typeNameParameter : typeNameParameters) {
- try {
- Class> typeParameter = canonicalTypeNameToType(typeNameParameter);
- typeParameters.add(typeParameter);
- } catch (IllegalArgumentException iae) {
+ Class> typeParameter = canonicalTypeNameToType(typeNameParameter);
+
+ if (typeParameter == null) {
throw new IllegalArgumentException("type parameter [" + typeNameParameter + "] not found " +
- "for constructor [[" + targetCanonicalClassName + "], " + typeNameParameters + "]", iae);
+ "for constructor [[" + targetCanonicalClassName + "], " + typeNameParameters + "]");
}
+
+ typeParameters.add(typeParameter);
}
addPainlessConstructor(targetClass, typeParameters);
@@ -357,11 +362,9 @@ public void addPainlessConstructor(Class> targetClass, List> typePara
List> javaTypeParameters = new ArrayList<>(typeParametersSize);
for (Class> typeParameter : typeParameters) {
- try {
- validateType(typeParameter);
- } catch (IllegalArgumentException iae) {
+ if (isValidType(typeParameter) == false) {
throw new IllegalArgumentException("type parameter [" + typeToCanonicalTypeName(typeParameter) + "] not found " +
- "for constructor [[" + targetCanonicalClassName + "], " + typesToCanonicalTypeNames(typeParameters) + "]", iae);
+ "for constructor [[" + targetCanonicalClassName + "], " + typesToCanonicalTypeNames(typeParameters) + "]");
}
javaTypeParameters.add(typeToJavaType(typeParameter));
@@ -435,22 +438,21 @@ public void addPainlessMethod(ClassLoader classLoader, String targetCanonicalCla
List> typeParameters = new ArrayList<>(typeNameParameters.size());
for (String typeNameParameter : typeNameParameters) {
- try {
- Class> typeParameter = canonicalTypeNameToType(typeNameParameter);
- typeParameters.add(typeParameter);
- } catch (IllegalArgumentException iae) {
+ Class> typeParameter = canonicalTypeNameToType(typeNameParameter);
+
+ if (typeParameter == null) {
throw new IllegalArgumentException("parameter type [" + typeNameParameter + "] not found for method " +
- "[[" + targetCanonicalClassName + "], [" + methodName + "], " + typeNameParameters + "]", iae);
+ "[[" + targetCanonicalClassName + "], [" + methodName + "], " + typeNameParameters + "]");
}
+
+ typeParameters.add(typeParameter);
}
- Class> returnType;
+ Class> returnType = canonicalTypeNameToType(returnCanonicalTypeName);
- try {
- returnType = canonicalTypeNameToType(returnCanonicalTypeName);
- } catch (IllegalArgumentException iae) {
+ if (returnType == null) {
throw new IllegalArgumentException("parameter type [" + returnCanonicalTypeName + "] not found for method " +
- "[[" + targetCanonicalClassName + "], [" + methodName + "], " + typeNameParameters + "]", iae);
+ "[[" + targetCanonicalClassName + "], [" + methodName + "], " + typeNameParameters + "]");
}
addPainlessMethod(targetClass, augmentedClass, methodName, returnType, typeParameters);
@@ -490,22 +492,18 @@ public void addPainlessMethod(Class> targetClass, Class> augmentedClass, Str
}
for (Class> typeParameter : typeParameters) {
- try {
- validateType(typeParameter);
- } catch (IllegalArgumentException iae) {
+ if (isValidType(typeParameter) == false) {
throw new IllegalArgumentException("type parameter [" + typeToCanonicalTypeName(typeParameter) + "] " +
"not found for method [[" + targetCanonicalClassName + "], [" + methodName + "], " +
- typesToCanonicalTypeNames(typeParameters) + "]", iae);
+ typesToCanonicalTypeNames(typeParameters) + "]");
}
javaTypeParameters.add(typeToJavaType(typeParameter));
}
- try {
- validateType(returnType);
- } catch (IllegalArgumentException iae) {
+ if (isValidType(returnType) == false) {
throw new IllegalArgumentException("return type [" + typeToCanonicalTypeName(returnType) + "] not found for method " +
- "[[" + targetCanonicalClassName + "], [" + methodName + "], " + typesToCanonicalTypeNames(typeParameters) + "]", iae);
+ "[[" + targetCanonicalClassName + "], [" + methodName + "], " + typesToCanonicalTypeNames(typeParameters) + "]");
}
Method javaMethod;
@@ -620,11 +618,9 @@ public void addPainlessField(String targetCanonicalClassName, String fieldName,
throw new IllegalArgumentException("class [" + targetCanonicalClassName + "] not found");
}
- Class> typeParameter;
+ Class> typeParameter = canonicalTypeNameToType(typeNameParameter);
- try {
- typeParameter = canonicalTypeNameToType(typeNameParameter);
- } catch (IllegalArgumentException iae) {
+ if (typeParameter == null) {
throw new IllegalArgumentException("type parameter [" + typeNameParameter + "] not found " +
"for field [[" + targetCanonicalClassName + "], [" + fieldName + "]");
}
@@ -656,11 +652,9 @@ public void addPainlessField(Class> targetClass, String fieldName, Class> ty
throw new IllegalArgumentException("class [" + targetCanonicalClassName + "] not found");
}
- try {
- validateType(typeParameter);
- } catch (IllegalArgumentException iae) {
+ if (isValidType(typeParameter) == false) {
throw new IllegalArgumentException("type parameter [" + typeToCanonicalTypeName(typeParameter) + "] not found " +
- "for field [[" + targetCanonicalClassName + "], [" + fieldName + "]", iae);
+ "for field [[" + targetCanonicalClassName + "], [" + fieldName + "]");
}
Field javaField;
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 0a181c5f1b02d..f2eb434516961 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
@@ -20,7 +20,6 @@
package org.elasticsearch.painless.lookup;
import java.util.Arrays;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -101,45 +100,47 @@ public static Class> canonicalTypeNameToType(String canonicalTypeName, Map type) {
String canonicalTypeName = type.getCanonicalName();
- if (canonicalTypeName.startsWith(def.class.getCanonicalName())) {
+ if (canonicalTypeName == null) {
+ canonicalTypeName = ANONYMOUS_CLASS_NAME;
+ } else if (canonicalTypeName.startsWith(def.class.getCanonicalName())) {
canonicalTypeName = canonicalTypeName.replace(def.class.getCanonicalName(), DEF_CLASS_NAME);
}
@@ -252,22 +255,6 @@ 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);
-
- while (type.getComponentType() != null) {
- type = type.getComponentType();
- }
-
- if (classes.contains(type) == false) {
- throw new IllegalArgumentException("type [" + canonicalTypeName + "] not found");
- }
- }
-
/**
* 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.
@@ -357,6 +344,11 @@ public static String buildPainlessFieldKey(String fieldName) {
return fieldName;
}
+ /**
+ * The name for an anonymous class.
+ */
+ public static final String ANONYMOUS_CLASS_NAME = "$anonymous";
+
/**
* The def type name as specified in the source for a script.
*/
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java
index c58d51e45cb4d..3ad3018c61e34 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EExplicit.java
@@ -49,9 +49,9 @@ void extractVariables(Set variables) {
@Override
void analyze(Locals locals) {
- try {
- actual = locals.getPainlessLookup().canonicalTypeNameToType(type);
- } catch (IllegalArgumentException exception) {
+ actual = locals.getPainlessLookup().canonicalTypeNameToType(type);
+
+ if (actual == null) {
throw createError(new IllegalArgumentException("Not a type [" + type + "]."));
}
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 8585b7fc0bb54..73e4f176ea1ba 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
@@ -54,12 +54,11 @@ void extractVariables(Set variables) {
@Override
void analyze(Locals locals) {
- Class> clazz;
// ensure the specified type is part of the definition
- try {
- clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
- } catch (IllegalArgumentException exception) {
+ Class> clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
+
+ if (clazz == null) {
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EListInit.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EListInit.java
index bd931558b620d..8c9154aaaf304 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EListInit.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EListInit.java
@@ -33,6 +33,8 @@
import java.util.List;
import java.util.Set;
+import static org.elasticsearch.painless.lookup.PainlessLookupUtility.typeToCanonicalTypeName;
+
/**
* Represents a list initialization shortcut.
*/
@@ -63,16 +65,17 @@ void analyze(Locals locals) {
actual = ArrayList.class;
- try {
- constructor = locals.getPainlessLookup().lookupPainlessConstructor(actual, 0);
- } catch (IllegalArgumentException iae) {
- throw createError(iae);
+ constructor = locals.getPainlessLookup().lookupPainlessConstructor(actual, 0);
+
+ if (constructor == null) {
+ throw createError(new IllegalArgumentException(
+ "constructor [" + typeToCanonicalTypeName(actual) + ", /0] not found"));
}
- try {
- method = locals.getPainlessLookup().lookupPainlessMethod(actual, false, "add", 1);
- } catch (IllegalArgumentException iae) {
- throw createError(iae);
+ method = locals.getPainlessLookup().lookupPainlessMethod(actual, false, "add", 1);
+
+ if (method == null) {
+ throw createError(new IllegalArgumentException("method [" + typeToCanonicalTypeName(actual) + ", add/1] not found"));
}
for (int index = 0; index < values.size(); ++index) {
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EMapInit.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EMapInit.java
index 91332672c0510..11c12b2cd0a96 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EMapInit.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EMapInit.java
@@ -33,6 +33,8 @@
import java.util.List;
import java.util.Set;
+import static org.elasticsearch.painless.lookup.PainlessLookupUtility.typeToCanonicalTypeName;
+
/**
* Represents a map initialization shortcut.
*/
@@ -69,16 +71,17 @@ void analyze(Locals locals) {
actual = HashMap.class;
- try {
- constructor = locals.getPainlessLookup().lookupPainlessConstructor(actual, 0);
- } catch (IllegalArgumentException iae) {
- throw createError(iae);
+ constructor = locals.getPainlessLookup().lookupPainlessConstructor(actual, 0);
+
+ if (constructor == null) {
+ throw createError(new IllegalArgumentException(
+ "constructor [" + typeToCanonicalTypeName(actual) + ", /0] not found"));
}
- try {
- method = locals.getPainlessLookup().lookupPainlessMethod(actual, false, "put", 2);
- } catch (IllegalArgumentException iae) {
- throw createError(iae);
+ method = locals.getPainlessLookup().lookupPainlessMethod(actual, false, "put", 2);
+
+ if (method == null) {
+ throw createError(new IllegalArgumentException("method [" + typeToCanonicalTypeName(actual) + ", put/2] not found"));
}
if (keys.size() != values.size()) {
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewArray.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewArray.java
index e0a49ebd6158e..cef005de9c3bc 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewArray.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewArray.java
@@ -54,15 +54,13 @@ void extractVariables(Set variables) {
@Override
void analyze(Locals locals) {
- if (!read) {
- throw createError(new IllegalArgumentException("A newly created array must be read from."));
+ if (!read) {
+ throw createError(new IllegalArgumentException("A newly created array must be read from."));
}
- Class> clazz;
+ Class> clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
- try {
- clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
- } catch (IllegalArgumentException exception) {
+ if (clazz == null) {
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewObj.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewObj.java
index 55ba60feb3e77..9423ed5d109de 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewObj.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/ENewObj.java
@@ -32,6 +32,8 @@
import java.util.Objects;
import java.util.Set;
+import static org.elasticsearch.painless.lookup.PainlessLookupUtility.typeToCanonicalTypeName;
+
/**
* Represents and object instantiation.
*/
@@ -58,16 +60,17 @@ void extractVariables(Set variables) {
@Override
void analyze(Locals locals) {
- try {
- actual = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
- } catch (IllegalArgumentException exception) {
+ actual = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
+
+ if (actual == null) {
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
}
- try {
- constructor = locals.getPainlessLookup().lookupPainlessConstructor(actual, arguments.size());
- } catch (IllegalArgumentException iae) {
- throw createError(iae);
+ constructor = locals.getPainlessLookup().lookupPainlessConstructor(actual, arguments.size());
+
+ if (constructor == null) {
+ throw createError(new IllegalArgumentException(
+ "constructor [" + typeToCanonicalTypeName(actual) + ", /" + arguments.size() + "] not found"));
}
Class>[] types = new Class>[constructor.typeParameters.size()];
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EStatic.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EStatic.java
index e5909d93e9dc2..0d8c94db0f1fc 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EStatic.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/EStatic.java
@@ -47,9 +47,9 @@ void extractVariables(Set variables) {
@Override
void analyze(Locals locals) {
- try {
- actual = locals.getPainlessLookup().canonicalTypeNameToType(type);
- } catch (IllegalArgumentException exception) {
+ actual = locals.getPainlessLookup().canonicalTypeNameToType(type);
+
+ if (actual == null) {
throw createError(new IllegalArgumentException("Not a type [" + type + "]."));
}
}
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 9406b4ca41127..25ae1ed97742a 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
@@ -30,6 +30,8 @@
import java.util.Objects;
import java.util.Set;
+import static org.elasticsearch.painless.lookup.PainlessLookupUtility.typeToCanonicalTypeName;
+
/**
* Represents a method call and defers to a child subnode.
*/
@@ -67,13 +69,15 @@ void analyze(Locals locals) {
if (prefix.actual == def.class) {
sub = new PSubDefCall(location, name, arguments);
} else {
- try {
- PainlessMethod method =
- locals.getPainlessLookup().lookupPainlessMethod(prefix.actual, prefix instanceof EStatic, name, arguments.size());
- sub = new PSubCallInvoke(location, method, prefix.actual, arguments);
- } catch (IllegalArgumentException iae) {
- throw createError(iae);
+ PainlessMethod method =
+ locals.getPainlessLookup().lookupPainlessMethod(prefix.actual, prefix instanceof EStatic, name, arguments.size());
+
+ if (method == null) {
+ throw createError(new IllegalArgumentException(
+ "method [" + typeToCanonicalTypeName(prefix.actual) + ", " + name + "/" + arguments.size() + "] not found"));
}
+
+ sub = new PSubCallInvoke(location, method, prefix.actual, arguments);
}
if (nullSafe) {
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 59cbfd405b7fd..7efd6a29899c4 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
@@ -23,6 +23,7 @@
import org.elasticsearch.painless.Locals;
import org.elasticsearch.painless.Location;
import org.elasticsearch.painless.MethodWriter;
+import org.elasticsearch.painless.lookup.PainlessField;
import org.elasticsearch.painless.lookup.PainlessLookupUtility;
import org.elasticsearch.painless.lookup.PainlessMethod;
import org.elasticsearch.painless.lookup.def;
@@ -32,6 +33,8 @@
import java.util.Objects;
import java.util.Set;
+import static org.elasticsearch.painless.lookup.PainlessLookupUtility.typeToCanonicalTypeName;
+
/**
* Represents a field load/store and defers to a child subnode.
*/
@@ -65,31 +68,22 @@ void analyze(Locals locals) {
} else if (prefix.actual == def.class) {
sub = new PSubDefField(location, value);
} else {
- try {
- sub = new PSubField(location,
- locals.getPainlessLookup().lookupPainlessField(prefix.actual, prefix instanceof EStatic, value));
- } catch (IllegalArgumentException fieldIAE) {
+ PainlessField field = locals.getPainlessLookup().lookupPainlessField(prefix.actual, prefix instanceof EStatic, value);
+
+ if (field == null) {
PainlessMethod getter;
PainlessMethod setter;
- try {
+ getter = locals.getPainlessLookup().lookupPainlessMethod(prefix.actual, false,
+ "get" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 0);
+
+ if (getter == null) {
getter = locals.getPainlessLookup().lookupPainlessMethod(prefix.actual, false,
- "get" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 0);
- } catch (IllegalArgumentException getIAE) {
- try {
- getter = locals.getPainlessLookup().lookupPainlessMethod(prefix.actual, false,
- "is" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 0);
- } catch (IllegalArgumentException isIAE) {
- getter = null;
- }
+ "is" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 0);
}
- try {
- setter = locals.getPainlessLookup().lookupPainlessMethod(prefix.actual, false,
- "set" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 0);
- } catch (IllegalArgumentException setIAE) {
- setter = null;
- }
+ setter = locals.getPainlessLookup().lookupPainlessMethod(prefix.actual, false,
+ "set" + Character.toUpperCase(value.charAt(0)) + value.substring(1), 0);
if (getter != null || setter != null) {
sub = new PSubShortcut(location, value, PainlessLookupUtility.typeToCanonicalTypeName(prefix.actual), getter, setter);
@@ -107,8 +101,11 @@ void analyze(Locals locals) {
}
if (sub == null) {
- throw createError(fieldIAE);
+ throw createError(new IllegalArgumentException(
+ "field [" + typeToCanonicalTypeName(prefix.actual) + ", " + value + "] not found"));
}
+ } else {
+ sub = new PSubField(location, field);
}
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubListShortcut.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubListShortcut.java
index 838756fcc67b4..3bc4913fde940 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubListShortcut.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubListShortcut.java
@@ -57,12 +57,8 @@ void extractVariables(Set variables) {
void analyze(Locals locals) {
String canonicalClassName = PainlessLookupUtility.typeToCanonicalTypeName(targetClass);
- try {
- getter = locals.getPainlessLookup().lookupPainlessMethod(targetClass, false, "get", 1);
- setter = locals.getPainlessLookup().lookupPainlessMethod(targetClass, false, "set", 2);
- } catch (IllegalArgumentException iae) {
- throw createError(iae);
- }
+ getter = locals.getPainlessLookup().lookupPainlessMethod(targetClass, false, "get", 1);
+ setter = locals.getPainlessLookup().lookupPainlessMethod(targetClass, false, "set", 2);
if (getter != null && (getter.returnType == void.class || getter.typeParameters.size() != 1 ||
getter.typeParameters.get(0) != int.class)) {
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubMapShortcut.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubMapShortcut.java
index 27a3f69775aa9..0a0f099bd6841 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubMapShortcut.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/PSubMapShortcut.java
@@ -56,12 +56,8 @@ void extractVariables(Set variables) {
void analyze(Locals locals) {
String canonicalClassName = PainlessLookupUtility.typeToCanonicalTypeName(targetClass);
- try {
- getter = locals.getPainlessLookup().lookupPainlessMethod(targetClass, false, "get", 1);
- setter = locals.getPainlessLookup().lookupPainlessMethod(targetClass, false, "put", 2);
- } catch (IllegalArgumentException iae) {
- throw createError(iae);
- }
+ getter = locals.getPainlessLookup().lookupPainlessMethod(targetClass, false, "get", 1);
+ setter = locals.getPainlessLookup().lookupPainlessMethod(targetClass, false, "put", 2);
if (getter != null && (getter.returnType == void.class || getter.typeParameters.size() != 1)) {
throw createError(new IllegalArgumentException("Illegal map get shortcut for type [" + canonicalClassName + "]."));
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SCatch.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SCatch.java
index 04b0462b53383..0c8ba5de6b2cf 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SCatch.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SCatch.java
@@ -64,11 +64,9 @@ void extractVariables(Set variables) {
@Override
void analyze(Locals locals) {
- Class> clazz;
+ Class> clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
- try {
- clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
- } catch (IllegalArgumentException exception) {
+ if (clazz == null) {
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
}
diff --git a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java
index f3774885cfd58..7ead673c70b7a 100644
--- a/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java
+++ b/modules/lang-painless/src/main/java/org/elasticsearch/painless/node/SDeclaration.java
@@ -59,11 +59,9 @@ void extractVariables(Set variables) {
@Override
void analyze(Locals locals) {
- Class> clazz;
+ Class> clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
- try {
- clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
- } catch (IllegalArgumentException exception) {
+ if (clazz == null) {
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
}
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 a83f501df3292..cf41105c4fe36 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
@@ -68,11 +68,9 @@ void analyze(Locals locals) {
expression.expected = expression.actual;
expression = expression.cast(locals);
- Class> clazz;
+ Class> clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
- try {
- clazz = locals.getPainlessLookup().canonicalTypeNameToType(this.type);
- } catch (IllegalArgumentException exception) {
+ if (clazz == null) {
throw createError(new IllegalArgumentException("Not a type [" + this.type + "]."));
}
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 4a844c7bc30ef..6fe09627f9dfd 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
@@ -115,9 +115,9 @@ void extractVariables(Set variables) {
}
void generateSignature(PainlessLookup painlessLookup) {
- try {
- returnType = painlessLookup.canonicalTypeNameToType(rtnTypeStr);
- } catch (IllegalArgumentException exception) {
+ returnType = painlessLookup.canonicalTypeNameToType(rtnTypeStr);
+
+ if (returnType == null) {
throw createError(new IllegalArgumentException("Illegal return type [" + rtnTypeStr + "] for function [" + name + "]."));
}
@@ -129,16 +129,16 @@ void generateSignature(PainlessLookup painlessLookup) {
List> paramTypes = new ArrayList<>();
for (int param = 0; param < this.paramTypeStrs.size(); ++param) {
- try {
Class> paramType = painlessLookup.canonicalTypeNameToType(this.paramTypeStrs.get(param));
- paramClasses[param] = PainlessLookupUtility.typeToJavaType(paramType);
- paramTypes.add(paramType);
- parameters.add(new Parameter(location, paramNameStrs.get(param), paramType));
- } catch (IllegalArgumentException exception) {
+ if (paramType == null) {
throw createError(new IllegalArgumentException(
"Illegal parameter type [" + this.paramTypeStrs.get(param) + "] for function [" + name + "]."));
}
+
+ paramClasses[param] = PainlessLookupUtility.typeToJavaType(paramType);
+ paramTypes.add(paramType);
+ parameters.add(new Parameter(location, paramNameStrs.get(param), paramType));
}
typeParameters = paramTypes;
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 577d1d51d09b0..46dfa056874f2 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
@@ -40,6 +40,7 @@
import static org.elasticsearch.painless.WriterConstants.ITERATOR_HASNEXT;
import static org.elasticsearch.painless.WriterConstants.ITERATOR_NEXT;
import static org.elasticsearch.painless.WriterConstants.ITERATOR_TYPE;
+import static org.elasticsearch.painless.lookup.PainlessLookupUtility.typeToCanonicalTypeName;
/**
* Represents a for-each loop for iterables.
@@ -76,10 +77,11 @@ void analyze(Locals locals) {
if (expression.actual == def.class) {
method = null;
} else {
- try {
- method = locals.getPainlessLookup().lookupPainlessMethod(expression.actual, false, "iterator", 0);
- } catch (IllegalArgumentException iae) {
- throw createError(iae);
+ method = locals.getPainlessLookup().lookupPainlessMethod(expression.actual, false, "iterator", 0);
+
+ if (method == null) {
+ throw createError(new IllegalArgumentException(
+ "method [" + typeToCanonicalTypeName(expression.actual) + ", iterator/0] not found"));
}
}
diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefBootstrapTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefBootstrapTests.java
index 8a6aa2bbdc593..c4b85521e098f 100644
--- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefBootstrapTests.java
+++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/DefBootstrapTests.java
@@ -134,7 +134,7 @@ public void testMegamorphic() throws Throwable {
final IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> {
Integer.toString((int)handle.invokeExact(new Object()));
});
- assertEquals("Unable to find dynamic method [size] with [0] arguments for class [java.lang.Object].", iae.getMessage());
+ assertEquals("dynamic method [java.lang.Object, size/0] not found", iae.getMessage());
assertTrue("Does not fail inside ClassValue.computeValue()", Arrays.stream(iae.getStackTrace()).anyMatch(e -> {
return e.getMethodName().equals("computeValue") &&
e.getClassName().startsWith("org.elasticsearch.painless.DefBootstrap$PIC$");
diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/OverloadTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/OverloadTests.java
index 1b90d58299953..52c28799fae34 100644
--- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/OverloadTests.java
+++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/OverloadTests.java
@@ -37,7 +37,7 @@ public void testMethodDynamic() {
IllegalArgumentException expected = expectScriptThrows(IllegalArgumentException.class, () -> {
exec("def x = 'abc123abc'; return x.indexOf('c', 3, 'bogus');");
});
- assertTrue(expected.getMessage().contains("dynamic method [indexOf]"));
+ assertTrue(expected.getMessage().contains("dynamic method [java.lang.String, indexOf/3] not found"));
}
public void testConstructor() {
diff --git a/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java b/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java
index 8eeb25c9676c7..f2d93aa759d07 100644
--- a/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java
+++ b/modules/lang-painless/src/test/java/org/elasticsearch/painless/WhenThingsGoWrongTests.java
@@ -219,7 +219,7 @@ public void testIllegalDynamicMethod() {
IllegalArgumentException expected = expectScriptThrows(IllegalArgumentException.class, () -> {
exec("def x = 'test'; return x.getClass().toString()");
});
- assertTrue(expected.getMessage().contains("Unable to find dynamic method"));
+ assertTrue(expected.getMessage().contains("dynamic method [java.lang.String, getClass/0] not found"));
}
public void testDynamicNPE() {