Skip to content
This repository was archived by the owner on Oct 16, 2024. It is now read-only.

Commit 1b4c026

Browse files
authored
#325 Reduce boxing in equals and merge methods
2 parents 15f1180 + 376c82a commit 1b4c026

File tree

5 files changed

+85
-76
lines changed

5 files changed

+85
-76
lines changed

src/main/java/org/inferred/freebuilder/processor/CodeGenerator.java

+31-30
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import org.inferred.freebuilder.processor.util.Excerpts;
4545
import org.inferred.freebuilder.processor.util.FieldAccess;
4646
import org.inferred.freebuilder.processor.util.ObjectsExcerpts;
47+
import org.inferred.freebuilder.processor.util.ObjectsExcerpts.Nullability;
4748
import org.inferred.freebuilder.processor.util.PreconditionExcerpts;
4849
import org.inferred.freebuilder.processor.util.SourceBuilder;
4950

@@ -385,10 +386,11 @@ private static void addValueTypeEquals(SourceBuilder code, Metadata metadata) {
385386
String prefix = " return ";
386387
for (Property property : metadata.getProperties()) {
387388
body.add(prefix);
388-
body.add("%s.equals(%s, %s)",
389-
body.feature(SOURCE_LEVEL).javaUtilObjects().get(),
389+
body.add(ObjectsExcerpts.equals(
390390
property.getField(),
391-
property.getField().on("other"));
391+
property.getField().on("other"),
392+
property.getType().getKind(),
393+
nullabilityOf(property, false)));
392394
prefix = "\n && ";
393395
}
394396
body.add(";\n");
@@ -398,7 +400,7 @@ private static void addValueTypeEquals(SourceBuilder code, Metadata metadata) {
398400
property.getField(),
399401
property.getField().on("other"),
400402
property.getType().getKind(),
401-
(property.getCodeGenerator().getType() == Type.OPTIONAL) ? NULLABLE : NOT_NULLABLE))
403+
nullabilityOf(property, false)))
402404
.addLine(" return false;")
403405
.addLine(" }");
404406
}
@@ -472,10 +474,11 @@ private static void addPartialType(SourceBuilder code, Metadata metadata) {
472474
String prefix = " return ";
473475
for (Property property : metadata.getProperties()) {
474476
body.add(prefix);
475-
body.add("%s.equals(%s, %s)",
476-
body.feature(SOURCE_LEVEL).javaUtilObjects().get(),
477+
body.add(ObjectsExcerpts.equals(
477478
property.getField(),
478-
property.getField().on("other"));
479+
property.getField().on("other"),
480+
property.getType().getKind(),
481+
nullabilityOf(property, true)));
479482
prefix = "\n && ";
480483
}
481484
if (hasRequiredProperties) {
@@ -488,29 +491,12 @@ private static void addPartialType(SourceBuilder code, Metadata metadata) {
488491
body.add(";\n");
489492
} else {
490493
for (Property property : metadata.getProperties()) {
491-
switch (property.getType().getKind()) {
492-
case FLOAT:
493-
case DOUBLE:
494-
body.addLine(" if (%s.doubleToLongBits(%s)", Double.class, property.getField())
495-
.addLine(" != %s.doubleToLongBits(%s)) {",
496-
Double.class, property.getField().on("other"));
497-
break;
498-
499-
default:
500-
if (property.getType().getKind().isPrimitive()) {
501-
body.addLine(" if (%s != %s) {",
502-
property.getField(), property.getField().on("other"));
503-
} else if (property.getCodeGenerator().getType() == Type.HAS_DEFAULT) {
504-
body.addLine(" if (!%s.equals(%s)) {",
505-
property.getField(), property.getField().on("other"));
506-
} else {
507-
body.addLine(" if (%s != %s",
508-
property.getField(), property.getField().on("other"))
509-
.addLine(" && (%1$s == null || !%1$s.equals(%2$s))) {",
510-
property.getField(), property.getField().on("other"));
511-
}
512-
}
513-
body.addLine(" return false;")
494+
body.addLine(" if (%s) {", ObjectsExcerpts.notEquals(
495+
property.getField(),
496+
property.getField().on("other"),
497+
property.getType().getKind(),
498+
nullabilityOf(property, true)))
499+
.addLine(" return false;")
514500
.addLine(" }");
515501
}
516502
if (hasRequiredProperties) {
@@ -589,6 +575,21 @@ private void writeStubSource(SourceBuilder code, Metadata metadata) {
589575
.addLine("abstract class %s {}", metadata.getGeneratedBuilder().declaration());
590576
}
591577

578+
private static Nullability nullabilityOf(Property property, boolean inPartial) {
579+
switch (property.getCodeGenerator().getType()) {
580+
case HAS_DEFAULT:
581+
return NOT_NULLABLE;
582+
583+
case OPTIONAL:
584+
return NULLABLE;
585+
586+
case REQUIRED:
587+
return inPartial ? NULLABLE : NOT_NULLABLE;
588+
}
589+
throw new IllegalStateException(
590+
"Unexpected property type " + property.getCodeGenerator().getType());
591+
}
592+
592593
/** Returns an {@link Excerpt} of "implements/extends {@code type}". */
593594
private static Excerpt extending(final Object type, final boolean isInterface) {
594595
return Excerpts.add(isInterface ? "implements %s" : "extends %s", type);

src/main/java/org/inferred/freebuilder/processor/util/ObjectsExcerpts.java

+28-20
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import static org.inferred.freebuilder.processor.util.feature.SourceLevel.SOURCE_LEVEL;
44

5+
import com.google.common.base.Preconditions;
6+
57
import javax.lang.model.type.TypeKind;
68

79
public class ObjectsExcerpts {
@@ -52,32 +54,41 @@ private static class EqualsExcerpt extends Excerpt {
5254

5355
@Override
5456
public void addTo(SourceBuilder code) {
55-
QualifiedName javaUtilObjects = code.feature(SOURCE_LEVEL).javaUtilObjects().orNull();
56-
if (javaUtilObjects != null) {
57-
code.add("%s%s.equals(%s, %s)", areEqual ? "" : "!", javaUtilObjects, a, b);
58-
} else if (nullability.isNullable()) {
59-
if (areEqual) {
60-
code.add("%1$s == %2$s || (%1$s != null && %1$s.equals(%2$s))", a, b);
61-
} else {
62-
code.add("%1$s != %2$s && (%1$s == null || !%1$s.equals(%2$s))", a, b);
63-
}
64-
} else if (kind.isPrimitive()) {
65-
switch (kind) {
57+
switch (kind) {
6658
case FLOAT:
6759
code.add("%1$s.floatToIntBits(%2$s) %3$s %1$s.floatToIntBits(%4$s)",
6860
Float.class, a, areEqual ? "==" : "!=", b);
69-
break;
61+
return;
7062

7163
case DOUBLE:
7264
code.add("%1$s.doubleToLongBits(%2$s) %3$s %1$s.doubleToLongBits(%4$s)",
7365
Double.class, a, areEqual ? "==" : "!=", b);
74-
break;
66+
return;
67+
68+
case BOOLEAN:
69+
case BYTE:
70+
case SHORT:
71+
case INT:
72+
case LONG:
73+
case CHAR:
74+
code.add("%s %s %s", a, areEqual ? "==" : "!=", b);
75+
return;
7576

7677
default:
77-
code.add("%s %s %s", a, areEqual ? "==" : "!=", b);
78-
}
79-
} else {
80-
code.add("%s%s.equals(%s)", areEqual ? "" : "!", a, b);
78+
Preconditions.checkState(!kind.isPrimitive(), "Unexpected primitive type " + kind);
79+
QualifiedName javaUtilObjects = code.feature(SOURCE_LEVEL).javaUtilObjects().orNull();
80+
if (javaUtilObjects != null) {
81+
code.add("%s%s.equals(%s, %s)", areEqual ? "" : "!", javaUtilObjects, a, b);
82+
} else if (nullability.isNullable()) {
83+
if (areEqual) {
84+
code.add("%1$s == %2$s || (%1$s != null && %1$s.equals(%2$s))", a, b);
85+
} else {
86+
code.add("%1$s != %2$s && (%1$s == null || !%1$s.equals(%2$s))", a, b);
87+
}
88+
} else {
89+
code.add("%s%s.equals(%s)", areEqual ? "" : "!", a, b);
90+
}
91+
return;
8192
}
8293
}
8394

@@ -89,10 +100,7 @@ protected void addFields(FieldReceiver fields) {
89100
fields.add("kind", kind);
90101
fields.add("nullable", nullability);
91102
}
92-
93103
}
94104

95-
96-
97105
private ObjectsExcerpts() {}
98106
}

src/test/java/org/inferred/freebuilder/processor/DefaultedPropertiesSourceTest.java

+12-12
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ public void testJ7() {
296296
" if (!Objects.equals(value.getName(), _defaults.getName())) {",
297297
" setName(value.getName());",
298298
" }",
299-
" if (!Objects.equals(value.getAge(), _defaults.getAge())) {",
299+
" if (value.getAge() != _defaults.getAge()) {",
300300
" setAge(value.getAge());",
301301
" }",
302302
" return (Person.Builder) this;",
@@ -312,7 +312,7 @@ public void testJ7() {
312312
" if (!Objects.equals(template.getName(), _defaults.getName())) {",
313313
" setName(template.getName());",
314314
" }",
315-
" if (!Objects.equals(template.getAge(), _defaults.getAge())) {",
315+
" if (template.getAge() != _defaults.getAge()) {",
316316
" setAge(template.getAge());",
317317
" }",
318318
" return (Person.Builder) this;",
@@ -374,7 +374,7 @@ public void testJ7() {
374374
" return false;",
375375
" }",
376376
" Person_Builder.Value other = (Person_Builder.Value) obj;",
377-
" return Objects.equals(name, other.name) && Objects.equals(age, other.age);",
377+
" return Objects.equals(name, other.name) && age == other.age;",
378378
" }",
379379
"",
380380
" @Override",
@@ -413,7 +413,7 @@ public void testJ7() {
413413
" return false;",
414414
" }",
415415
" Person_Builder.Partial other = (Person_Builder.Partial) obj;",
416-
" return Objects.equals(name, other.name) && Objects.equals(age, other.age);",
416+
" return Objects.equals(name, other.name) && age == other.age;",
417417
" }",
418418
"",
419419
" @Override",
@@ -710,7 +710,7 @@ public void testJ8() {
710710
" if (!Objects.equals(value.getName(), _defaults.getName())) {",
711711
" setName(value.getName());",
712712
" }",
713-
" if (!Objects.equals(value.getAge(), _defaults.getAge())) {",
713+
" if (value.getAge() != _defaults.getAge()) {",
714714
" setAge(value.getAge());",
715715
" }",
716716
" return (Person.Builder) this;",
@@ -726,7 +726,7 @@ public void testJ8() {
726726
" if (!Objects.equals(template.getName(), _defaults.getName())) {",
727727
" setName(template.getName());",
728728
" }",
729-
" if (!Objects.equals(template.getAge(), _defaults.getAge())) {",
729+
" if (template.getAge() != _defaults.getAge()) {",
730730
" setAge(template.getAge());",
731731
" }",
732732
" return (Person.Builder) this;",
@@ -788,7 +788,7 @@ public void testJ8() {
788788
" return false;",
789789
" }",
790790
" Person_Builder.Value other = (Person_Builder.Value) obj;",
791-
" return Objects.equals(name, other.name) && Objects.equals(age, other.age);",
791+
" return Objects.equals(name, other.name) && age == other.age;",
792792
" }",
793793
"",
794794
" @Override",
@@ -827,7 +827,7 @@ public void testJ8() {
827827
" return false;",
828828
" }",
829829
" Person_Builder.Partial other = (Person_Builder.Partial) obj;",
830-
" return Objects.equals(name, other.name) && Objects.equals(age, other.age);",
830+
" return Objects.equals(name, other.name) && age == other.age;",
831831
" }",
832832
"",
833833
" @Override",
@@ -922,7 +922,7 @@ public void testJ8_toBuilder() {
922922
" if (!Objects.equals(value.getName(), _defaults.getName())) {",
923923
" setName(value.getName());",
924924
" }",
925-
" if (!Objects.equals(value.getAge(), _defaults.getAge())) {",
925+
" if (value.getAge() != _defaults.getAge()) {",
926926
" setAge(value.getAge());",
927927
" }",
928928
" return (Person.Builder) this;",
@@ -938,7 +938,7 @@ public void testJ8_toBuilder() {
938938
" if (!Objects.equals(template.getName(), _defaults.getName())) {",
939939
" setName(template.getName());",
940940
" }",
941-
" if (!Objects.equals(template.getAge(), _defaults.getAge())) {",
941+
" if (template.getAge() != _defaults.getAge()) {",
942942
" setAge(template.getAge());",
943943
" }",
944944
" return (Person.Builder) this;",
@@ -1005,7 +1005,7 @@ public void testJ8_toBuilder() {
10051005
" return false;",
10061006
" }",
10071007
" Person_Builder.Value other = (Person_Builder.Value) obj;",
1008-
" return Objects.equals(name, other.name) && Objects.equals(age, other.age);",
1008+
" return Objects.equals(name, other.name) && age == other.age;",
10091009
" }",
10101010
"",
10111011
" @Override",
@@ -1059,7 +1059,7 @@ public void testJ8_toBuilder() {
10591059
" return false;",
10601060
" }",
10611061
" Person_Builder.Partial other = (Person_Builder.Partial) obj;",
1062-
" return Objects.equals(name, other.name) && Objects.equals(age, other.age);",
1062+
" return Objects.equals(name, other.name) && age == other.age;",
10631063
" }",
10641064
"",
10651065
" @Override",

src/test/java/org/inferred/freebuilder/processor/RequiredPropertiesSourceTest.java

+12-12
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ public void testJ7() {
398398
" setName(value.getName());",
399399
" }",
400400
" if (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
401-
" || !Objects.equals(value.getAge(), _defaults.getAge())) {",
401+
" || value.getAge() != _defaults.getAge()) {",
402402
" setAge(value.getAge());",
403403
" }",
404404
" return (Person.Builder) this;",
@@ -420,7 +420,7 @@ public void testJ7() {
420420
" }",
421421
" if (!base._unsetProperties.contains(Person_Builder.Property.AGE)",
422422
" && (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
423-
" || !Objects.equals(template.getAge(), _defaults.getAge()))) {",
423+
" || template.getAge() != _defaults.getAge())) {",
424424
" setAge(template.getAge());",
425425
" }",
426426
" return (Person.Builder) this;",
@@ -491,7 +491,7 @@ public void testJ7() {
491491
" return false;",
492492
" }",
493493
" Person_Builder.Value other = (Person_Builder.Value) obj;",
494-
" return Objects.equals(name, other.name) && Objects.equals(age, other.age);",
494+
" return Objects.equals(name, other.name) && age == other.age;",
495495
" }",
496496
"",
497497
" @Override",
@@ -539,7 +539,7 @@ public void testJ7() {
539539
" }",
540540
" Person_Builder.Partial other = (Person_Builder.Partial) obj;",
541541
" return Objects.equals(name, other.name)",
542-
" && Objects.equals(age, other.age)",
542+
" && age == other.age",
543543
" && Objects.equals(_unsetProperties, other._unsetProperties);",
544544
" }",
545545
"",
@@ -929,7 +929,7 @@ public void testJ7_noGuava() {
929929
" setName(value.getName());",
930930
" }",
931931
" if (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
932-
" || !Objects.equals(value.getAge(), _defaults.getAge())) {",
932+
" || value.getAge() != _defaults.getAge()) {",
933933
" setAge(value.getAge());",
934934
" }",
935935
" return (Person.Builder) this;",
@@ -951,7 +951,7 @@ public void testJ7_noGuava() {
951951
" }",
952952
" if (!base._unsetProperties.contains(Person_Builder.Property.AGE)",
953953
" && (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
954-
" || !Objects.equals(template.getAge(), _defaults.getAge()))) {",
954+
" || template.getAge() != _defaults.getAge())) {",
955955
" setAge(template.getAge());",
956956
" }",
957957
" return (Person.Builder) this;",
@@ -1022,7 +1022,7 @@ public void testJ7_noGuava() {
10221022
" return false;",
10231023
" }",
10241024
" Person_Builder.Value other = (Person_Builder.Value) obj;",
1025-
" return Objects.equals(name, other.name) && Objects.equals(age, other.age);",
1025+
" return Objects.equals(name, other.name) && age == other.age;",
10261026
" }",
10271027
"",
10281028
" @Override",
@@ -1070,7 +1070,7 @@ public void testJ7_noGuava() {
10701070
" }",
10711071
" Person_Builder.Partial other = (Person_Builder.Partial) obj;",
10721072
" return Objects.equals(name, other.name)",
1073-
" && Objects.equals(age, other.age)",
1073+
" && age == other.age",
10741074
" && Objects.equals(_unsetProperties, other._unsetProperties);",
10751075
" }",
10761076
"",
@@ -1214,7 +1214,7 @@ public void testJ8() {
12141214
" setName(value.getName());",
12151215
" }",
12161216
" if (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
1217-
" || !Objects.equals(value.getAge(), _defaults.getAge())) {",
1217+
" || value.getAge() != _defaults.getAge()) {",
12181218
" setAge(value.getAge());",
12191219
" }",
12201220
" return (Person.Builder) this;",
@@ -1236,7 +1236,7 @@ public void testJ8() {
12361236
" }",
12371237
" if (!base._unsetProperties.contains(Person_Builder.Property.AGE)",
12381238
" && (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
1239-
" || !Objects.equals(template.getAge(), _defaults.getAge()))) {",
1239+
" || template.getAge() != _defaults.getAge())) {",
12401240
" setAge(template.getAge());",
12411241
" }",
12421242
" return (Person.Builder) this;",
@@ -1307,7 +1307,7 @@ public void testJ8() {
13071307
" return false;",
13081308
" }",
13091309
" Person_Builder.Value other = (Person_Builder.Value) obj;",
1310-
" return Objects.equals(name, other.name) && Objects.equals(age, other.age);",
1310+
" return Objects.equals(name, other.name) && age == other.age;",
13111311
" }",
13121312
"",
13131313
" @Override",
@@ -1355,7 +1355,7 @@ public void testJ8() {
13551355
" }",
13561356
" Person_Builder.Partial other = (Person_Builder.Partial) obj;",
13571357
" return Objects.equals(name, other.name)",
1358-
" && Objects.equals(age, other.age)",
1358+
" && age == other.age",
13591359
" && Objects.equals(_unsetProperties, other._unsetProperties);",
13601360
" }",
13611361
"",

0 commit comments

Comments
 (0)