|
@@ -56,18 +56,14 @@ import static org.elasticsearch.painless.lookup.PainlessLookupUtility.typesToCan
|
|
|
|
|
|
public final class PainlessLookupBuilder {
|
|
|
|
|
|
- private static final Map<PainlessConstructor, PainlessConstructor> painlessConstructorCache = new HashMap<>();
|
|
|
- private static final Map<PainlessMethod, PainlessMethod> painlessMethodCache = new HashMap<>();
|
|
|
- private static final Map<PainlessField, PainlessField> painlessFieldCache = new HashMap<>();
|
|
|
- private static final Map<PainlessClassBinding, PainlessClassBinding> painlessClassBindingCache = new HashMap<>();
|
|
|
- private static final Map<PainlessInstanceBinding, PainlessInstanceBinding> painlessInstanceBindingCache = new HashMap<>();
|
|
|
- private static final Map<PainlessMethod, PainlessMethod> painlessFilteredCache = new HashMap<>();
|
|
|
-
|
|
|
private static final Pattern CLASS_NAME_PATTERN = Pattern.compile("^[_a-zA-Z][._a-zA-Z0-9]*$");
|
|
|
- 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 final Pattern METHOD_AND_FIELD_NAME_PATTERN = Pattern.compile("^[_a-zA-Z][_a-zA-Z0-9]*$");
|
|
|
|
|
|
- public static PainlessLookup buildFromWhitelists(List<Whitelist> whitelists) {
|
|
|
+ public static PainlessLookup buildFromWhitelists(
|
|
|
+ List<Whitelist> whitelists,
|
|
|
+ Map<Object, Object> dedup,
|
|
|
+ Map<PainlessMethod, PainlessMethod> filteredMethodCache
|
|
|
+ ) {
|
|
|
PainlessLookupBuilder painlessLookupBuilder = new PainlessLookupBuilder();
|
|
|
String origin = "internal error";
|
|
|
|
|
@@ -92,7 +88,8 @@ public final class PainlessLookupBuilder {
|
|
|
painlessLookupBuilder.addPainlessConstructor(
|
|
|
targetCanonicalClassName,
|
|
|
whitelistConstructor.canonicalTypeNameParameters,
|
|
|
- whitelistConstructor.painlessAnnotations
|
|
|
+ whitelistConstructor.painlessAnnotations,
|
|
|
+ dedup
|
|
|
);
|
|
|
}
|
|
|
|
|
@@ -105,7 +102,8 @@ public final class PainlessLookupBuilder {
|
|
|
whitelistMethod.methodName,
|
|
|
whitelistMethod.returnCanonicalTypeName,
|
|
|
whitelistMethod.canonicalTypeNameParameters,
|
|
|
- whitelistMethod.painlessAnnotations
|
|
|
+ whitelistMethod.painlessAnnotations,
|
|
|
+ dedup
|
|
|
);
|
|
|
}
|
|
|
|
|
@@ -116,7 +114,8 @@ public final class PainlessLookupBuilder {
|
|
|
targetCanonicalClassName,
|
|
|
whitelistField.fieldName,
|
|
|
whitelistField.canonicalTypeNameParameter,
|
|
|
- whitelistField.painlessAnnotations
|
|
|
+ whitelistField.painlessAnnotations,
|
|
|
+ dedup
|
|
|
);
|
|
|
}
|
|
|
}
|
|
@@ -129,7 +128,8 @@ public final class PainlessLookupBuilder {
|
|
|
whitelistStatic.methodName,
|
|
|
whitelistStatic.returnCanonicalTypeName,
|
|
|
whitelistStatic.canonicalTypeNameParameters,
|
|
|
- whitelistStatic.painlessAnnotations
|
|
|
+ whitelistStatic.painlessAnnotations,
|
|
|
+ dedup
|
|
|
);
|
|
|
}
|
|
|
|
|
@@ -141,7 +141,8 @@ public final class PainlessLookupBuilder {
|
|
|
whitelistClassBinding.methodName,
|
|
|
whitelistClassBinding.returnCanonicalTypeName,
|
|
|
whitelistClassBinding.canonicalTypeNameParameters,
|
|
|
- whitelistClassBinding.painlessAnnotations
|
|
|
+ whitelistClassBinding.painlessAnnotations,
|
|
|
+ dedup
|
|
|
);
|
|
|
}
|
|
|
|
|
@@ -152,7 +153,8 @@ public final class PainlessLookupBuilder {
|
|
|
whitelistInstanceBinding.methodName,
|
|
|
whitelistInstanceBinding.returnCanonicalTypeName,
|
|
|
whitelistInstanceBinding.canonicalTypeNameParameters,
|
|
|
- whitelistInstanceBinding.painlessAnnotations
|
|
|
+ whitelistInstanceBinding.painlessAnnotations,
|
|
|
+ dedup
|
|
|
);
|
|
|
}
|
|
|
}
|
|
@@ -160,7 +162,7 @@ public final class PainlessLookupBuilder {
|
|
|
throw new IllegalArgumentException("error loading whitelist(s) " + origin, exception);
|
|
|
}
|
|
|
|
|
|
- return painlessLookupBuilder.build();
|
|
|
+ return painlessLookupBuilder.build(dedup, filteredMethodCache);
|
|
|
}
|
|
|
|
|
|
// javaClassNamesToClasses is all the classes that need to be available to the custom classloader
|
|
@@ -269,7 +271,7 @@ public final class PainlessLookupBuilder {
|
|
|
return new IllegalArgumentException(Strings.format(formatText, args), cause);
|
|
|
}
|
|
|
|
|
|
- public void addPainlessClass(Class<?> clazz, Map<Class<?>, Object> annotations) {
|
|
|
+ private void addPainlessClass(Class<?> clazz, Map<Class<?>, Object> annotations) {
|
|
|
Objects.requireNonNull(clazz);
|
|
|
Objects.requireNonNull(annotations);
|
|
|
|
|
@@ -355,10 +357,11 @@ public final class PainlessLookupBuilder {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public void addPainlessConstructor(
|
|
|
+ private void addPainlessConstructor(
|
|
|
String targetCanonicalClassName,
|
|
|
List<String> canonicalTypeNameParameters,
|
|
|
- Map<Class<?>, Object> annotations
|
|
|
+ Map<Class<?>, Object> annotations,
|
|
|
+ Map<Object, Object> dedup
|
|
|
) {
|
|
|
Objects.requireNonNull(targetCanonicalClassName);
|
|
|
Objects.requireNonNull(canonicalTypeNameParameters);
|
|
@@ -391,10 +394,15 @@ public final class PainlessLookupBuilder {
|
|
|
typeParameters.add(typeParameter);
|
|
|
}
|
|
|
|
|
|
- addPainlessConstructor(targetClass, typeParameters, annotations);
|
|
|
+ addPainlessConstructor(targetClass, typeParameters, annotations, dedup);
|
|
|
}
|
|
|
|
|
|
- public void addPainlessConstructor(Class<?> targetClass, List<Class<?>> typeParameters, Map<Class<?>, Object> annotations) {
|
|
|
+ private void addPainlessConstructor(
|
|
|
+ Class<?> targetClass,
|
|
|
+ List<Class<?>> typeParameters,
|
|
|
+ Map<Class<?>, Object> annotations,
|
|
|
+ Map<Object, Object> dedup
|
|
|
+ ) {
|
|
|
Objects.requireNonNull(targetClass);
|
|
|
Objects.requireNonNull(typeParameters);
|
|
|
|
|
@@ -473,7 +481,7 @@ public final class PainlessLookupBuilder {
|
|
|
);
|
|
|
|
|
|
if (existingPainlessConstructor == null) {
|
|
|
- newPainlessConstructor = painlessConstructorCache.computeIfAbsent(newPainlessConstructor, Function.identity());
|
|
|
+ newPainlessConstructor = (PainlessConstructor) dedup.computeIfAbsent(newPainlessConstructor, Function.identity());
|
|
|
painlessClassBuilder.constructors.put(painlessConstructorKey.intern(), newPainlessConstructor);
|
|
|
} else if (newPainlessConstructor.equals(existingPainlessConstructor) == false) {
|
|
|
throw lookupException(
|
|
@@ -486,14 +494,15 @@ public final class PainlessLookupBuilder {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public void addPainlessMethod(
|
|
|
+ private void addPainlessMethod(
|
|
|
ClassLoader classLoader,
|
|
|
String targetCanonicalClassName,
|
|
|
String augmentedCanonicalClassName,
|
|
|
String methodName,
|
|
|
String returnCanonicalTypeName,
|
|
|
List<String> canonicalTypeNameParameters,
|
|
|
- Map<Class<?>, Object> annotations
|
|
|
+ Map<Class<?>, Object> annotations,
|
|
|
+ Map<Object, Object> dedup
|
|
|
) {
|
|
|
|
|
|
Objects.requireNonNull(classLoader);
|
|
@@ -561,7 +570,7 @@ public final class PainlessLookupBuilder {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- addPainlessMethod(targetClass, augmentedClass, methodName, returnType, typeParameters, annotations);
|
|
|
+ addPainlessMethod(targetClass, augmentedClass, methodName, returnType, typeParameters, annotations, dedup);
|
|
|
}
|
|
|
|
|
|
public void addPainlessMethod(
|
|
@@ -570,7 +579,8 @@ public final class PainlessLookupBuilder {
|
|
|
String methodName,
|
|
|
Class<?> returnType,
|
|
|
List<Class<?>> typeParameters,
|
|
|
- Map<Class<?>, Object> annotations
|
|
|
+ Map<Class<?>, Object> annotations,
|
|
|
+ Map<Object, Object> dedup
|
|
|
) {
|
|
|
|
|
|
Objects.requireNonNull(targetClass);
|
|
@@ -585,7 +595,7 @@ public final class PainlessLookupBuilder {
|
|
|
|
|
|
String targetCanonicalClassName = typeToCanonicalTypeName(targetClass);
|
|
|
|
|
|
- if (METHOD_NAME_PATTERN.matcher(methodName).matches() == false) {
|
|
|
+ if (METHOD_AND_FIELD_NAME_PATTERN.matcher(methodName).matches() == false) {
|
|
|
throw new IllegalArgumentException(
|
|
|
"invalid method name [" + methodName + "] for target class [" + targetCanonicalClassName + "]."
|
|
|
);
|
|
@@ -748,7 +758,7 @@ public final class PainlessLookupBuilder {
|
|
|
);
|
|
|
|
|
|
if (existingPainlessMethod == null) {
|
|
|
- newPainlessMethod = painlessMethodCache.computeIfAbsent(newPainlessMethod, key -> key);
|
|
|
+ newPainlessMethod = (PainlessMethod) dedup.computeIfAbsent(newPainlessMethod, Function.identity());
|
|
|
|
|
|
if (isStatic) {
|
|
|
painlessClassBuilder.staticMethods.put(painlessMethodKey.intern(), newPainlessMethod);
|
|
@@ -771,12 +781,13 @@ public final class PainlessLookupBuilder {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public void addPainlessField(
|
|
|
+ private void addPainlessField(
|
|
|
ClassLoader classLoader,
|
|
|
String targetCanonicalClassName,
|
|
|
String fieldName,
|
|
|
String canonicalTypeNameParameter,
|
|
|
- Map<Class<?>, Object> annotations
|
|
|
+ Map<Class<?>, Object> annotations,
|
|
|
+ Map<Object, Object> dedup
|
|
|
) {
|
|
|
|
|
|
Objects.requireNonNull(classLoader);
|
|
@@ -827,15 +838,16 @@ public final class PainlessLookupBuilder {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- addPainlessField(targetClass, augmentedClass, fieldName, typeParameter, annotations);
|
|
|
+ addPainlessField(targetClass, augmentedClass, fieldName, typeParameter, annotations, dedup);
|
|
|
}
|
|
|
|
|
|
- public void addPainlessField(
|
|
|
+ private void addPainlessField(
|
|
|
Class<?> targetClass,
|
|
|
Class<?> augmentedClass,
|
|
|
String fieldName,
|
|
|
Class<?> typeParameter,
|
|
|
- Map<Class<?>, Object> annotations
|
|
|
+ Map<Class<?>, Object> annotations,
|
|
|
+ Map<Object, Object> dedup
|
|
|
) {
|
|
|
|
|
|
Objects.requireNonNull(targetClass);
|
|
@@ -849,7 +861,7 @@ public final class PainlessLookupBuilder {
|
|
|
|
|
|
String targetCanonicalClassName = typeToCanonicalTypeName(targetClass);
|
|
|
|
|
|
- if (FIELD_NAME_PATTERN.matcher(fieldName).matches() == false) {
|
|
|
+ if (METHOD_AND_FIELD_NAME_PATTERN.matcher(fieldName).matches() == false) {
|
|
|
throw new IllegalArgumentException(
|
|
|
"invalid field name [" + fieldName + "] for target class [" + targetCanonicalClassName + "]."
|
|
|
);
|
|
@@ -946,7 +958,7 @@ public final class PainlessLookupBuilder {
|
|
|
PainlessField newPainlessField = new PainlessField(javaField, typeParameter, annotations, methodHandleGetter, null);
|
|
|
|
|
|
if (existingPainlessField == null) {
|
|
|
- newPainlessField = painlessFieldCache.computeIfAbsent(newPainlessField, Function.identity());
|
|
|
+ newPainlessField = (PainlessField) dedup.computeIfAbsent(newPainlessField, Function.identity());
|
|
|
painlessClassBuilder.staticFields.put(painlessFieldKey.intern(), newPainlessField);
|
|
|
} else if (newPainlessField.equals(existingPainlessField) == false) {
|
|
|
throw lookupException(
|
|
@@ -981,7 +993,7 @@ public final class PainlessLookupBuilder {
|
|
|
);
|
|
|
|
|
|
if (existingPainlessField == null) {
|
|
|
- newPainlessField = painlessFieldCache.computeIfAbsent(newPainlessField, key -> key);
|
|
|
+ newPainlessField = (PainlessField) dedup.computeIfAbsent(newPainlessField, Function.identity());
|
|
|
painlessClassBuilder.fields.put(painlessFieldKey.intern(), newPainlessField);
|
|
|
} else if (newPainlessField.equals(existingPainlessField) == false) {
|
|
|
throw lookupException(
|
|
@@ -1004,7 +1016,8 @@ public final class PainlessLookupBuilder {
|
|
|
String methodName,
|
|
|
String returnCanonicalTypeName,
|
|
|
List<String> canonicalTypeNameParameters,
|
|
|
- Map<Class<?>, Object> annotations
|
|
|
+ Map<Class<?>, Object> annotations,
|
|
|
+ Map<Object, Object> dedup
|
|
|
) {
|
|
|
|
|
|
Objects.requireNonNull(classLoader);
|
|
@@ -1046,7 +1059,7 @@ public final class PainlessLookupBuilder {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- addImportedPainlessMethod(targetClass, methodName, returnType, typeParameters, annotations);
|
|
|
+ addImportedPainlessMethod(targetClass, methodName, returnType, typeParameters, annotations, dedup);
|
|
|
}
|
|
|
|
|
|
public void addImportedPainlessMethod(
|
|
@@ -1054,7 +1067,8 @@ public final class PainlessLookupBuilder {
|
|
|
String methodName,
|
|
|
Class<?> returnType,
|
|
|
List<Class<?>> typeParameters,
|
|
|
- Map<Class<?>, Object> annotations
|
|
|
+ Map<Class<?>, Object> annotations,
|
|
|
+ Map<Object, Object> dedup
|
|
|
) {
|
|
|
Objects.requireNonNull(targetClass);
|
|
|
Objects.requireNonNull(methodName);
|
|
@@ -1077,7 +1091,7 @@ public final class PainlessLookupBuilder {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- if (METHOD_NAME_PATTERN.matcher(methodName).matches() == false) {
|
|
|
+ if (METHOD_AND_FIELD_NAME_PATTERN.matcher(methodName).matches() == false) {
|
|
|
throw new IllegalArgumentException(
|
|
|
"invalid imported method name [" + methodName + "] for target class [" + targetCanonicalClassName + "]."
|
|
|
);
|
|
@@ -1182,7 +1196,7 @@ public final class PainlessLookupBuilder {
|
|
|
);
|
|
|
|
|
|
if (existingImportedPainlessMethod == null) {
|
|
|
- newImportedPainlessMethod = painlessMethodCache.computeIfAbsent(newImportedPainlessMethod, key -> key);
|
|
|
+ newImportedPainlessMethod = (PainlessMethod) dedup.computeIfAbsent(newImportedPainlessMethod, Function.identity());
|
|
|
painlessMethodKeysToImportedPainlessMethods.put(painlessMethodKey.intern(), newImportedPainlessMethod);
|
|
|
} else if (newImportedPainlessMethod.equals(existingImportedPainlessMethod) == false) {
|
|
|
throw lookupException(
|
|
@@ -1206,7 +1220,8 @@ public final class PainlessLookupBuilder {
|
|
|
String methodName,
|
|
|
String returnCanonicalTypeName,
|
|
|
List<String> canonicalTypeNameParameters,
|
|
|
- Map<Class<?>, Object> annotations
|
|
|
+ Map<Class<?>, Object> annotations,
|
|
|
+ Map<Object, Object> dedup
|
|
|
) {
|
|
|
|
|
|
Objects.requireNonNull(classLoader);
|
|
@@ -1247,15 +1262,16 @@ public final class PainlessLookupBuilder {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- addPainlessClassBinding(targetClass, methodName, returnType, typeParameters, annotations);
|
|
|
+ addPainlessClassBinding(targetClass, methodName, returnType, typeParameters, annotations, dedup);
|
|
|
}
|
|
|
|
|
|
- public void addPainlessClassBinding(
|
|
|
+ private void addPainlessClassBinding(
|
|
|
Class<?> targetClass,
|
|
|
String methodName,
|
|
|
Class<?> returnType,
|
|
|
List<Class<?>> typeParameters,
|
|
|
- Map<Class<?>, Object> annotations
|
|
|
+ Map<Class<?>, Object> annotations,
|
|
|
+ Map<Object, Object> dedup
|
|
|
) {
|
|
|
Objects.requireNonNull(targetClass);
|
|
|
Objects.requireNonNull(methodName);
|
|
@@ -1333,7 +1349,7 @@ public final class PainlessLookupBuilder {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (METHOD_NAME_PATTERN.matcher(methodName).matches() == false) {
|
|
|
+ if (METHOD_AND_FIELD_NAME_PATTERN.matcher(methodName).matches() == false) {
|
|
|
throw new IllegalArgumentException(
|
|
|
"invalid method name [" + methodName + "] for class binding [" + targetCanonicalClassName + "]."
|
|
|
);
|
|
@@ -1446,7 +1462,7 @@ public final class PainlessLookupBuilder {
|
|
|
);
|
|
|
|
|
|
if (existingPainlessClassBinding == null) {
|
|
|
- newPainlessClassBinding = painlessClassBindingCache.computeIfAbsent(newPainlessClassBinding, Function.identity());
|
|
|
+ newPainlessClassBinding = (PainlessClassBinding) dedup.computeIfAbsent(newPainlessClassBinding, Function.identity());
|
|
|
painlessMethodKeysToPainlessClassBindings.put(painlessMethodKey.intern(), newPainlessClassBinding);
|
|
|
} else if (newPainlessClassBinding.equals(existingPainlessClassBinding) == false) {
|
|
|
throw lookupException(
|
|
@@ -1469,7 +1485,8 @@ public final class PainlessLookupBuilder {
|
|
|
String methodName,
|
|
|
String returnCanonicalTypeName,
|
|
|
List<String> canonicalTypeNameParameters,
|
|
|
- Map<Class<?>, Object> painlessAnnotations
|
|
|
+ Map<Class<?>, Object> painlessAnnotations,
|
|
|
+ Map<Object, Object> dedup
|
|
|
) {
|
|
|
|
|
|
Objects.requireNonNull(targetInstance);
|
|
@@ -1509,7 +1526,7 @@ public final class PainlessLookupBuilder {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- addPainlessInstanceBinding(targetInstance, methodName, returnType, typeParameters, painlessAnnotations);
|
|
|
+ addPainlessInstanceBinding(targetInstance, methodName, returnType, typeParameters, painlessAnnotations, dedup);
|
|
|
}
|
|
|
|
|
|
public void addPainlessInstanceBinding(
|
|
@@ -1517,7 +1534,8 @@ public final class PainlessLookupBuilder {
|
|
|
String methodName,
|
|
|
Class<?> returnType,
|
|
|
List<Class<?>> typeParameters,
|
|
|
- Map<Class<?>, Object> painlessAnnotations
|
|
|
+ Map<Class<?>, Object> painlessAnnotations,
|
|
|
+ Map<Object, Object> dedup
|
|
|
) {
|
|
|
Objects.requireNonNull(targetInstance);
|
|
|
Objects.requireNonNull(methodName);
|
|
@@ -1542,7 +1560,7 @@ public final class PainlessLookupBuilder {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- if (METHOD_NAME_PATTERN.matcher(methodName).matches() == false) {
|
|
|
+ if (METHOD_AND_FIELD_NAME_PATTERN.matcher(methodName).matches() == false) {
|
|
|
throw new IllegalArgumentException(
|
|
|
"invalid method name [" + methodName + "] for instance binding [" + targetCanonicalClassName + "]."
|
|
|
);
|
|
@@ -1629,7 +1647,7 @@ public final class PainlessLookupBuilder {
|
|
|
);
|
|
|
|
|
|
if (existingPainlessInstanceBinding == null) {
|
|
|
- newPainlessInstanceBinding = painlessInstanceBindingCache.computeIfAbsent(newPainlessInstanceBinding, key -> key);
|
|
|
+ newPainlessInstanceBinding = (PainlessInstanceBinding) dedup.computeIfAbsent(newPainlessInstanceBinding, Function.identity());
|
|
|
painlessMethodKeysToPainlessInstanceBindings.put(painlessMethodKey.intern(), newPainlessInstanceBinding);
|
|
|
} else if (newPainlessInstanceBinding.equals(existingPainlessInstanceBinding) == false) {
|
|
|
throw lookupException(
|
|
@@ -1649,16 +1667,19 @@ public final class PainlessLookupBuilder {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public PainlessLookup build() {
|
|
|
+ public PainlessLookup build(Map<Object, Object> dedup, Map<PainlessMethod, PainlessMethod> filteredMethodCache) {
|
|
|
buildPainlessClassHierarchy();
|
|
|
setFunctionalInterfaceMethods();
|
|
|
- generateRuntimeMethods();
|
|
|
+ generateRuntimeMethods(filteredMethodCache);
|
|
|
cacheRuntimeHandles();
|
|
|
|
|
|
Map<Class<?>, PainlessClass> classesToPainlessClasses = Maps.newMapWithExpectedSize(classesToPainlessClassBuilders.size());
|
|
|
|
|
|
for (Map.Entry<Class<?>, PainlessClassBuilder> painlessClassBuilderEntry : classesToPainlessClassBuilders.entrySet()) {
|
|
|
- classesToPainlessClasses.put(painlessClassBuilderEntry.getKey(), painlessClassBuilderEntry.getValue().build());
|
|
|
+ classesToPainlessClasses.put(
|
|
|
+ painlessClassBuilderEntry.getKey(),
|
|
|
+ (PainlessClass) dedup.computeIfAbsent(painlessClassBuilderEntry.getValue().build(), Function.identity())
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
if (javaClassNamesToClasses.values().containsAll(canonicalClassNamesToClasses.values()) == false) {
|
|
@@ -1817,7 +1838,7 @@ public final class PainlessLookupBuilder {
|
|
|
* {@link Map}. The {@link PainlessClass#runtimeMethods} {@link Map} is used exclusively to look up methods at
|
|
|
* run-time resulting from calls with a def type value target.
|
|
|
*/
|
|
|
- private void generateRuntimeMethods() {
|
|
|
+ private void generateRuntimeMethods(Map<PainlessMethod, PainlessMethod> filteredMethodCache) {
|
|
|
for (Map.Entry<Class<?>, PainlessClassBuilder> painlessClassBuilderEntry : classesToPainlessClassBuilders.entrySet()) {
|
|
|
Class<?> targetClass = painlessClassBuilderEntry.getKey();
|
|
|
PainlessClassBuilder painlessClassBuilder = painlessClassBuilderEntry.getValue();
|
|
@@ -1832,7 +1853,7 @@ public final class PainlessLookupBuilder {
|
|
|
|| typeParameter == Long.class
|
|
|
|| typeParameter == Float.class
|
|
|
|| typeParameter == Double.class) {
|
|
|
- generateFilteredMethod(targetClass, painlessClassBuilder, painlessMethod);
|
|
|
+ generateFilteredMethod(targetClass, painlessClassBuilder, painlessMethod, filteredMethodCache);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -1842,10 +1863,11 @@ public final class PainlessLookupBuilder {
|
|
|
private static void generateFilteredMethod(
|
|
|
Class<?> targetClass,
|
|
|
PainlessClassBuilder painlessClassBuilder,
|
|
|
- PainlessMethod painlessMethod
|
|
|
+ PainlessMethod painlessMethod,
|
|
|
+ Map<PainlessMethod, PainlessMethod> filteredMethodCache
|
|
|
) {
|
|
|
String painlessMethodKey = buildPainlessMethodKey(painlessMethod.javaMethod().getName(), painlessMethod.typeParameters().size());
|
|
|
- PainlessMethod filteredPainlessMethod = painlessFilteredCache.get(painlessMethod);
|
|
|
+ PainlessMethod filteredPainlessMethod = filteredMethodCache.get(painlessMethod);
|
|
|
|
|
|
if (filteredPainlessMethod == null) {
|
|
|
Method javaMethod = painlessMethod.javaMethod();
|
|
@@ -1899,7 +1921,7 @@ public final class PainlessLookupBuilder {
|
|
|
Map.of()
|
|
|
);
|
|
|
painlessClassBuilder.runtimeMethods.put(painlessMethodKey.intern(), filteredPainlessMethod);
|
|
|
- painlessFilteredCache.put(painlessMethod, filteredPainlessMethod);
|
|
|
+ filteredMethodCache.put(painlessMethod, filteredPainlessMethod);
|
|
|
} catch (Exception exception) {
|
|
|
throw new IllegalStateException(
|
|
|
"internal error occurred attempting to generate a runtime method [" + painlessMethodKey + "]",
|