Skip to content

Commit 7fbec4f

Browse files
authored
Use Objects.equals to compare record fields for null support (#10313)
This likely generates slightly more code than before, but the code it emits is correct. Fixes #10293
1 parent 6a2216c commit 7fbec4f

2 files changed

Lines changed: 14 additions & 12 deletions

File tree

dev/core/src/com/google/gwt/dev/jjs/impl/ImplementRecordComponents.java

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public static void exec(JProgram program) {
6161
private final JMethod getClassMethod;
6262
private final JMethod getSimpleNameMethod;
6363
private final JClassType javaLangString;
64+
private final JMethod objectsEquals;
6465

6566
private ImplementRecordComponents(JProgram program) {
6667
this.program = program;
@@ -69,6 +70,8 @@ private ImplementRecordComponents(JProgram program) {
6970
getClassMethod = program.getIndexedMethod(RuntimeConstants.OBJECT_GET_CLASS);
7071
getSimpleNameMethod = program.getIndexedMethod(RuntimeConstants.CLASS_GET_SIMPLE_NAME);
7172
javaLangString = program.getTypeJavaLangString();
73+
objectsEquals = program.getIndexedType("Objects")
74+
.findMethod("equals(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
7275
}
7376

7477
private void execImpl() {
@@ -190,28 +193,18 @@ private void implementEquals(JRecordType type, JMethod method, SourceInfo info)
190193
body.getBlock().addStmt(uncheckedAssign.makeStatement());
191194

192195
JExpression componentCheck = JBooleanLiteral.TRUE;
193-
JMethod objectEquals = program.getIndexedMethod(RuntimeConstants.OBJECT_EQUALS);
194196
for (JField field : type.getFields()) {
195197
if (!field.isStatic()) {
196198
JFieldRef myField = new JFieldRef(info, new JThisRef(info, type), field, type);
197199
JFieldRef otherField = new JFieldRef(info, typedOther.createRef(info), field, type);
198-
final JBinaryOperation equals;
200+
final JExpression equals;
199201
if (field.getType().isPrimitiveType()) {
200202
equals = new JBinaryOperation(info, JPrimitiveType.BOOLEAN,
201203
JBinaryOperator.EQ,
202204
myField,
203205
otherField);
204206
} else {
205-
// We would like to use Objects.equals here to be more concise, but we would need
206-
// to look up the right impl based on the field - just as simple to insert a null check
207-
// and get it a little closer to all being inlined away
208-
209-
// Make another field ref to call equals() on
210-
JFieldRef myField2 = new JFieldRef(info, new JThisRef(info, type), field, type);
211-
equals = new JBinaryOperation(info, JPrimitiveType.BOOLEAN, JBinaryOperator.AND,
212-
new JBinaryOperation(info, JPrimitiveType.BOOLEAN, JBinaryOperator.NEQ,
213-
myField, JNullLiteral.INSTANCE),
214-
new JMethodCall(info, myField2, objectEquals, otherField));
207+
equals = new JMethodCall(info, null, objectsEquals, myField, otherField);
215208
}
216209
if (componentCheck != JBooleanLiteral.TRUE) {
217210
componentCheck = new JBinaryOperation(info, JPrimitiveType.BOOLEAN,

user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java17Test.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ public String toString() {
185185
RecordWithReferenceType sameA = new RecordWithReferenceType(new TopLevelRecord("a", 1));
186186
RecordWithReferenceType sameB = new RecordWithReferenceType(new TopLevelRecord("a", 1));
187187
RecordWithReferenceType different = new RecordWithReferenceType(new TopLevelRecord("a", 2));
188+
RecordWithReferenceType nullChild = new RecordWithReferenceType(null);
188189
// check that an instance is equal to itself
189190
assertEquals(sameA, sameA);
190191
assertEquals(sameA.hashCode(), sameA.hashCode());
@@ -196,6 +197,14 @@ public String toString() {
196197
assertFalse(sameA.hashCode() == different.hashCode());
197198

198199
assertFalse(sameA.equals(null));
200+
assertFalse(nullChild.equals(sameA));
201+
assertFalse(sameA.equals(nullChild));
202+
assertTrue(new RecordWithReferenceType(null).equals(nullChild));
203+
assertTrue(nullChild.equals(nullChild));
204+
205+
assertTrue(new TopLevelRecord(null, 1).equals(new TopLevelRecord(null, 1)));
206+
assertFalse(new TopLevelRecord("asdf", 2).equals(new TopLevelRecord(null, 2)));
207+
assertFalse(new TopLevelRecord(null, 3).equals(new TopLevelRecord("abc", 3)));
199208
}
200209

201210
/**

0 commit comments

Comments
 (0)