Skip to content

Commit f2f4738

Browse files
committed
Painless: Cleanup Cache (#33963)
* Adds equals/hashcode methods to the Painless* objects within the lookup package. * Changes the caches to use the Painless* objects as keys as well as values. This forces future changes to taken into account the appropriate values for caching. * Deletes the existing caching objects in favor of Painless* objects. This removes a pair of bugs that were not taking into account subtle corner cases related to augmented methods and caching. * Uses the Painless* objects to check for equivalency in existing Painless* objects that may have already been added to a PainlessClass. This removes a bug related to return not being appropriately checked when adding methods. * Cleans up several error messages.
1 parent a136217 commit f2f4738

File tree

8 files changed

+336
-322
lines changed

8 files changed

+336
-322
lines changed

modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessCast.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,38 +19,59 @@
1919

2020
package org.elasticsearch.painless.lookup;
2121

22+
import java.util.Objects;
23+
2224
public class PainlessCast {
2325

2426
/** Create a standard cast with no boxing/unboxing. */
2527
public static PainlessCast originalTypetoTargetType(Class<?> originalType, Class<?> targetType, boolean explicitCast) {
28+
Objects.requireNonNull(originalType);
29+
Objects.requireNonNull(targetType);
30+
2631
return new PainlessCast(originalType, targetType, explicitCast, null, null, null, null);
2732
}
2833

2934
/** Create a cast where the original type will be unboxed, and then the cast will be performed. */
3035
public static PainlessCast unboxOriginalType(
3136
Class<?> originalType, Class<?> targetType, boolean explicitCast, Class<?> unboxOriginalType) {
3237

38+
Objects.requireNonNull(originalType);
39+
Objects.requireNonNull(targetType);
40+
Objects.requireNonNull(unboxOriginalType);
41+
3342
return new PainlessCast(originalType, targetType, explicitCast, unboxOriginalType, null, null, null);
3443
}
3544

3645
/** Create a cast where the target type will be unboxed, and then the cast will be performed. */
3746
public static PainlessCast unboxTargetType(
3847
Class<?> originalType, Class<?> targetType, boolean explicitCast, Class<?> unboxTargetType) {
3948

49+
Objects.requireNonNull(originalType);
50+
Objects.requireNonNull(targetType);
51+
Objects.requireNonNull(unboxTargetType);
52+
4053
return new PainlessCast(originalType, targetType, explicitCast, null, unboxTargetType, null, null);
4154
}
4255

4356
/** Create a cast where the original type will be boxed, and then the cast will be performed. */
4457
public static PainlessCast boxOriginalType(
4558
Class<?> originalType, Class<?> targetType, boolean explicitCast, Class<?> boxOriginalType) {
4659

60+
Objects.requireNonNull(originalType);
61+
Objects.requireNonNull(targetType);
62+
Objects.requireNonNull(boxOriginalType);
63+
4764
return new PainlessCast(originalType, targetType, explicitCast, null, null, boxOriginalType, null);
4865
}
4966

5067
/** Create a cast where the target type will be boxed, and then the cast will be performed. */
5168
public static PainlessCast boxTargetType(
5269
Class<?> originalType, Class<?> targetType, boolean explicitCast, Class<?> boxTargetType) {
5370

71+
Objects.requireNonNull(originalType);
72+
Objects.requireNonNull(targetType);
73+
Objects.requireNonNull(boxTargetType);
74+
5475
return new PainlessCast(originalType, targetType, explicitCast, null, null, null, boxTargetType);
5576
}
5677

@@ -73,4 +94,30 @@ private PainlessCast(Class<?> originalType, Class<?> targetType, boolean explici
7394
this.boxOriginalType = boxOriginalType;
7495
this.boxTargetType = boxTargetType;
7596
}
97+
98+
@Override
99+
public boolean equals(Object object) {
100+
if (this == object) {
101+
return true;
102+
}
103+
104+
if (object == null || getClass() != object.getClass()) {
105+
return false;
106+
}
107+
108+
PainlessCast that = (PainlessCast)object;
109+
110+
return explicitCast == that.explicitCast &&
111+
Objects.equals(originalType, that.originalType) &&
112+
Objects.equals(targetType, that.targetType) &&
113+
Objects.equals(unboxOriginalType, that.unboxOriginalType) &&
114+
Objects.equals(unboxTargetType, that.unboxTargetType) &&
115+
Objects.equals(boxOriginalType, that.boxOriginalType) &&
116+
Objects.equals(boxTargetType, that.boxTargetType);
117+
}
118+
119+
@Override
120+
public int hashCode() {
121+
return Objects.hash(originalType, targetType, explicitCast, unboxOriginalType, unboxTargetType, boxOriginalType, boxTargetType);
122+
}
76123
}

modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessClass.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.lang.invoke.MethodHandle;
2323
import java.util.Collections;
2424
import java.util.Map;
25+
import java.util.Objects;
2526

2627
public final class PainlessClass {
2728

@@ -57,4 +58,29 @@ public final class PainlessClass {
5758

5859
this.functionalInterfaceMethod = functionalInterfaceMethod;
5960
}
61+
62+
@Override
63+
public boolean equals(Object object) {
64+
if (this == object) {
65+
return true;
66+
}
67+
68+
if (object == null || getClass() != object.getClass()) {
69+
return false;
70+
}
71+
72+
PainlessClass that = (PainlessClass)object;
73+
74+
return Objects.equals(constructors, that.constructors) &&
75+
Objects.equals(staticMethods, that.staticMethods) &&
76+
Objects.equals(methods, that.methods) &&
77+
Objects.equals(staticFields, that.staticFields) &&
78+
Objects.equals(fields, that.fields) &&
79+
Objects.equals(functionalInterfaceMethod, that.functionalInterfaceMethod);
80+
}
81+
82+
@Override
83+
public int hashCode() {
84+
return Objects.hash(constructors, staticMethods, methods, staticFields, fields, functionalInterfaceMethod);
85+
}
6086
}

modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessClassBinding.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.lang.reflect.Constructor;
2323
import java.lang.reflect.Method;
2424
import java.util.List;
25+
import java.util.Objects;
2526

2627
public class PainlessClassBinding {
2728

@@ -38,4 +39,28 @@ public class PainlessClassBinding {
3839
this.returnType = returnType;
3940
this.typeParameters = typeParameters;
4041
}
42+
43+
@Override
44+
public boolean equals(Object object) {
45+
if (this == object) {
46+
return true;
47+
}
48+
49+
if (object == null || getClass() != object.getClass()) {
50+
return false;
51+
}
52+
53+
PainlessClassBinding that = (PainlessClassBinding)object;
54+
55+
return Objects.equals(javaConstructor, that.javaConstructor) &&
56+
Objects.equals(javaMethod, that.javaMethod) &&
57+
Objects.equals(returnType, that.returnType) &&
58+
Objects.equals(typeParameters, that.typeParameters);
59+
}
60+
61+
@Override
62+
public int hashCode() {
63+
64+
return Objects.hash(javaConstructor, javaMethod, returnType, typeParameters);
65+
}
4166
}

modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessClassBuilder.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.lang.invoke.MethodHandle;
2323
import java.util.HashMap;
2424
import java.util.Map;
25+
import java.util.Objects;
2526

2627
final class PainlessClassBuilder {
2728

@@ -57,4 +58,29 @@ PainlessClass build() {
5758
return new PainlessClass(constructors, staticMethods, methods, staticFields, fields,
5859
getterMethodHandles, setterMethodHandles, functionalInterfaceMethod);
5960
}
61+
62+
@Override
63+
public boolean equals(Object object) {
64+
if (this == object) {
65+
return true;
66+
}
67+
68+
if (object == null || getClass() != object.getClass()) {
69+
return false;
70+
}
71+
72+
PainlessClassBuilder that = (PainlessClassBuilder)object;
73+
74+
return Objects.equals(constructors, that.constructors) &&
75+
Objects.equals(staticMethods, that.staticMethods) &&
76+
Objects.equals(methods, that.methods) &&
77+
Objects.equals(staticFields, that.staticFields) &&
78+
Objects.equals(fields, that.fields) &&
79+
Objects.equals(functionalInterfaceMethod, that.functionalInterfaceMethod);
80+
}
81+
82+
@Override
83+
public int hashCode() {
84+
return Objects.hash(constructors, staticMethods, methods, staticFields, fields, functionalInterfaceMethod);
85+
}
6086
}

modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessConstructor.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.lang.invoke.MethodType;
2424
import java.lang.reflect.Constructor;
2525
import java.util.List;
26+
import java.util.Objects;
2627

2728
public class PainlessConstructor {
2829

@@ -37,4 +38,26 @@ public class PainlessConstructor {
3738
this.methodHandle = methodHandle;
3839
this.methodType = methodType;
3940
}
41+
42+
@Override
43+
public boolean equals(Object object) {
44+
if (this == object) {
45+
return true;
46+
}
47+
48+
if (object == null || getClass() != object.getClass()) {
49+
return false;
50+
}
51+
52+
PainlessConstructor that = (PainlessConstructor)object;
53+
54+
return Objects.equals(javaConstructor, that.javaConstructor) &&
55+
Objects.equals(typeParameters, that.typeParameters) &&
56+
Objects.equals(methodType, that.methodType);
57+
}
58+
59+
@Override
60+
public int hashCode() {
61+
return Objects.hash(javaConstructor, typeParameters, methodType);
62+
}
4063
}

modules/lang-painless/src/main/java/org/elasticsearch/painless/lookup/PainlessField.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import java.lang.invoke.MethodHandle;
2323
import java.lang.reflect.Field;
24+
import java.util.Objects;
2425

2526
public final class PainlessField {
2627

@@ -37,4 +38,25 @@ public final class PainlessField {
3738
this.getterMethodHandle = getterMethodHandle;
3839
this.setterMethodHandle = setterMethodHandle;
3940
}
41+
42+
@Override
43+
public boolean equals(Object object) {
44+
if (this == object) {
45+
return true;
46+
}
47+
48+
if (object == null || getClass() != object.getClass()) {
49+
return false;
50+
}
51+
52+
PainlessField that = (PainlessField)object;
53+
54+
return Objects.equals(javaField, that.javaField) &&
55+
Objects.equals(typeParameter, that.typeParameter);
56+
}
57+
58+
@Override
59+
public int hashCode() {
60+
return Objects.hash(javaField, typeParameter);
61+
}
4062
}

0 commit comments

Comments
 (0)