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

Commit 01730ed

Browse files
authored
Merge pull request #267 from google/issue/265.sorted.set.clear
Fix SortedSetProperty clear bug
2 parents 9f6ef47 + d580fc6 commit 01730ed

12 files changed

+363
-50
lines changed

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

+8-1
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,14 @@ private void addClear(SourceBuilder code, Metadata metadata) {
421421
.addLine("public %s %s() {", metadata.getBuilder(), clearMethod(property));
422422
if (code.feature(GUAVA).isAvailable()) {
423423
code.addLine(" if (%s instanceof %s) {", property.getField(), ImmutableSortedSet.class)
424-
.addLine(" %s = %s.of();", property.getField(), ImmutableSortedSet.class)
424+
.addLine(" if (%s.isEmpty()) {", property.getField())
425+
.addLine(" // Do nothing")
426+
.addLine(" } else if (%s.comparator() != null) {", property.getField())
427+
.addLine(" %1$s = new %2$s<%3$s>(%1$s.comparator()).build();",
428+
property.getField(), ImmutableSortedSet.Builder.class, elementType)
429+
.addLine(" } else {")
430+
.addLine(" %s = %s.of();", property.getField(), ImmutableSortedSet.class)
431+
.addLine(" }")
425432
.add(" } else ");
426433
}
427434
code.addLine(" if (%s != null) {", property.getField())

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

+80-16
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
11
package org.inferred.freebuilder.processor;
22

33
import static com.google.common.base.Preconditions.checkState;
4+
import static java.util.stream.Collectors.toList;
45

56
import com.google.common.collect.ImmutableList;
67
import com.google.common.collect.Ordering;
78

9+
import org.inferred.freebuilder.processor.testtype.AbstractNonComparable;
10+
import org.inferred.freebuilder.processor.testtype.NonComparable;
11+
import org.inferred.freebuilder.processor.testtype.OtherNonComparable;
812
import org.inferred.freebuilder.processor.util.NameImpl;
913

14+
import java.util.Collection;
15+
import java.util.Comparator;
16+
import java.util.List;
17+
import java.util.Optional;
1018
import java.util.stream.Collectors;
1119
import java.util.stream.IntStream;
1220

21+
import javax.annotation.Nullable;
22+
1323
public enum ElementFactory {
1424
STRINGS(
25+
String.class,
1526
"String",
16-
"String",
27+
null,
1728
CharSequence.class,
1829
"!element.isEmpty()",
1930
"!element.toString().isEmpty()",
@@ -28,8 +39,9 @@ public enum ElementFactory {
2839
"foxtrot",
2940
"golf"),
3041
INTEGERS(
31-
"Integer",
42+
Integer.class,
3243
"int",
44+
null,
3345
Number.class,
3446
"element >= 0",
3547
"element.intValue() >= 0",
@@ -42,49 +54,72 @@ public enum ElementFactory {
4254
10,
4355
15,
4456
21,
45-
28);
46-
47-
private final String type;
57+
28),
58+
NON_COMPARABLES(
59+
NonComparable.class,
60+
NonComparable.class.getName(),
61+
AbstractNonComparable.ReverseIdComparator.class,
62+
AbstractNonComparable.class,
63+
"element.id() >= 0",
64+
"element.id() >= 0",
65+
"ID must be non-negative",
66+
new NonComparable(-2, "broken"),
67+
new OtherNonComparable(88, "other"),
68+
new NonComparable(10, "alpha"),
69+
new NonComparable(9, "cappa"),
70+
new NonComparable(8, "echo"),
71+
new NonComparable(7, "golf"),
72+
new NonComparable(6, "beta"),
73+
new NonComparable(5, "delta"),
74+
new NonComparable(4, "foxtrot"));
75+
76+
private final Class<?> type;
4877
private final String unwrappedType;
78+
@Nullable private final Class<?> comparator;
4979
private Class<?> supertype;
5080
private final String validation;
5181
private final String supertypeValidation;
5282
private final String errorMessage;
53-
private final Comparable<?> invalidExample;
83+
private final Object invalidExample;
5484
private final Object supertypeExample;
55-
private final ImmutableList<Comparable<?>> examples;
85+
private final ImmutableList<Object> examples;
5686

5787
ElementFactory(
58-
String type,
88+
Class<?> type,
5989
String unwrappedType,
90+
@Nullable Class<? extends Comparator<?>> comparator,
6091
Class<?> supertype,
6192
String validation,
6293
String supertypeValidation,
6394
String errorMessage,
64-
Comparable<?> invalidExample,
95+
Object invalidExample,
6596
Object supertypeExample,
66-
Comparable<?>... examples) {
97+
Object... examples) {
6798
this.type = type;
6899
this.unwrappedType = unwrappedType;
100+
this.comparator = comparator;
69101
this.supertype = supertype;
70102
this.validation = validation;
71103
this.supertypeValidation = supertypeValidation;
72104
this.errorMessage = errorMessage;
73105
this.invalidExample = invalidExample;
74106
this.supertypeExample = supertypeExample;
75107
this.examples = ImmutableList.copyOf(examples);
76-
checkState(Ordering.natural().isOrdered(this.examples),
77-
"Examples must be in natural order (got %s)", this.examples);
108+
checkExamplesOrdered(comparator, this.examples);
78109
}
79110

80-
public String type() {
111+
public Class<?> type() {
81112
return type;
82113
}
83114

84115
public String unwrappedType() {
85116
return unwrappedType;
86117
}
87118

119+
public Optional<Class<?>> comparator() {
120+
return Optional.ofNullable(comparator);
121+
}
122+
88123
public Class<?> supertype() {
89124
return supertype;
90125
}
@@ -121,18 +156,47 @@ public String examples(int... ids) {
121156
return IntStream.of(ids).mapToObj(this::example).collect(Collectors.joining(", "));
122157
}
123158

159+
@Override
160+
public String toString() {
161+
return type.getSimpleName();
162+
}
163+
124164
private static String toSource(Object example) {
125165
if (example instanceof String) {
126166
return "\"" + example + "\"";
127167
} else if (example instanceof NameImpl) {
128168
return "new " + NameImpl.class.getName() + "(\"" + example + "\")";
169+
} else if (example instanceof NonComparable) {
170+
NonComparable nonComparable = (NonComparable) example;
171+
return "new " + NonComparable.class.getName() + "(" + nonComparable.id() + ", \""
172+
+ nonComparable.name() + "\")";
173+
} else if (example instanceof OtherNonComparable) {
174+
OtherNonComparable otherNonComparable = (OtherNonComparable) example;
175+
return "new " + OtherNonComparable.class.getName() + "(" + otherNonComparable.id() + ", \""
176+
+ otherNonComparable.name() + "\")";
129177
} else {
130178
return example.toString();
131179
}
132180
}
133181

134-
@Override
135-
public String toString() {
136-
return type;
182+
private static void checkExamplesOrdered(
183+
@Nullable Class<? extends Comparator<?>> comparator,
184+
Collection<?> examples) {
185+
if (comparator == null) {
186+
List<Comparable<?>> comparables =
187+
examples.stream().map(v -> (Comparable<?>) v).collect(toList());
188+
checkState(Ordering.natural().isOrdered(comparables),
189+
"Examples must be in natural order (got %s)", examples);
190+
} else {
191+
try {
192+
@SuppressWarnings("rawtypes")
193+
Ordering ordering = Ordering.from(comparator.newInstance());
194+
@SuppressWarnings("unchecked")
195+
boolean isOrdered = ordering.isOrdered(examples);
196+
checkState(isOrdered);
197+
} catch (ReflectiveOperationException e) {
198+
throw new RuntimeException(e);
199+
}
200+
}
137201
}
138202
}

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

+7-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.inferred.freebuilder.processor.util.testing.ParameterizedBehaviorTestFactory.Shared;
2929
import org.inferred.freebuilder.processor.util.testing.SourceBuilder;
3030
import org.inferred.freebuilder.processor.util.testing.TestBuilder;
31+
import org.junit.Before;
3132
import org.junit.Rule;
3233
import org.junit.Test;
3334
import org.junit.rules.ExpectedException;
@@ -114,7 +115,7 @@ public ListMutateMethodTest(
114115
elements.supertype());
115116
if (checked) {
116117
genericTypeBuilder
117-
.addLine(" @Override public Builder addItems(T element) {")
118+
.addLine(" @Override public Builder<T> addItems(T element) {")
118119
.addLine(" if (!(%s)) {", elements.supertypeValidation())
119120
.addLine(" throw new IllegalArgumentException(\"%s\");", elements.errorMessage())
120121
.addLine(" }")
@@ -145,6 +146,11 @@ public ListMutateMethodTest(
145146
}
146147
}
147148

149+
@Before
150+
public void setUp() {
151+
behaviorTester.withPermittedPackage(elements.type().getPackage());
152+
}
153+
148154
@Test
149155
public void mutateAndAddModifiesUnderlyingProperty() {
150156
behaviorTester

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

+6
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.inferred.freebuilder.processor.util.testing.ParameterizedBehaviorTestFactory.Shared;
3636
import org.inferred.freebuilder.processor.util.testing.SourceBuilder;
3737
import org.inferred.freebuilder.processor.util.testing.TestBuilder;
38+
import org.junit.Before;
3839
import org.junit.Rule;
3940
import org.junit.Test;
4041
import org.junit.rules.ExpectedException;
@@ -117,6 +118,11 @@ public ListPropertyTest(
117118
.build();
118119
}
119120

121+
@Before
122+
public void setUp() {
123+
behaviorTester.withPermittedPackage(elements.type().getPackage());
124+
}
125+
120126
@Test
121127
public void testDefaultEmpty() {
122128
behaviorTester

0 commit comments

Comments
 (0)