Skip to content

Commit

Permalink
Record.equals must accept null without an error (#10016)
Browse files Browse the repository at this point in the history
Fixes #10015
  • Loading branch information
niloc132 authored Oct 22, 2024
1 parent b47d247 commit 0056242
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -154,21 +154,30 @@ private void implementEquals(JRecordType type, JMethod method, SourceInfo info)
JMethodBody body = new JMethodBody(info);
JParameter otherParam = method.getParams().get(0);

// Equals is built from first == check between this and other, as a fast path for the same
// object and also to ensure that other isn't null. Then MyRecord.class == other.getClass(),
// and now we know they're the same type and can cast safely to access fields for the rest.
// if (this == other) return true;
JBinaryOperation eq =
new JBinaryOperation(info, JPrimitiveType.BOOLEAN, JBinaryOperator.EQ,
new JThisRef(info, type),
otherParam.createRef(info));
body.getBlock().addStmt(new JIfStatement(info, eq,
JBooleanLiteral.TRUE.makeReturnStatement(), null));

// other == null
JBinaryOperation nonNullCheck =
new JBinaryOperation(info, JPrimitiveType.BOOLEAN, JBinaryOperator.EQ,
otherParam.createRef(info), JNullLiteral.INSTANCE);
// MyRecordType.class != other.getClass()
JBinaryOperation sameTypeCheck =
new JBinaryOperation(info, JPrimitiveType.BOOLEAN, JBinaryOperator.NEQ,
new JClassLiteral(info, type),
new JMethodCall(info, otherParam.createRef(info), getClassMethod));
body.getBlock().addStmt(new JIfStatement(info, sameTypeCheck,
// other == null || MyRecordType.class != other.getClass()
JBinaryOperation nullAndTypeCheck =
new JBinaryOperation(info, JPrimitiveType.BOOLEAN, JBinaryOperator.OR,
nonNullCheck, sameTypeCheck);

// if (other == null || MyRecordType.class != other.getClass()) return false;
body.getBlock().addStmt(new JIfStatement(info, nullAndTypeCheck,
JBooleanLiteral.FALSE.makeReturnStatement(), null));

// Create a local to assign to and compare each component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ public String toString() {
assertFalse(0 == new TopLevelRecord("Pear", 0).hashCode());

assertFalse(new InnerRecord().equals(new LocalRecord()));
assertFalse(new InnerRecord().equals(null));
assertFalse(new LocalRecord().equals(null));

RecordWithReferenceType sameA = new RecordWithReferenceType(new TopLevelRecord("a", 1));
RecordWithReferenceType sameB = new RecordWithReferenceType(new TopLevelRecord("a", 1));
Expand All @@ -184,6 +186,8 @@ public String toString() {

assertFalse(sameA.equals(different));
assertFalse(sameA.hashCode() == different.hashCode());

assertFalse(sameA.equals(null));
}

/**
Expand Down

0 comments on commit 0056242

Please sign in to comment.