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

Commit 725d088

Browse files
authored
Merge pull request #209 from google/shared.lists
Share ImmutableLists
2 parents da96dbd + 0f1f36b commit 725d088

File tree

3 files changed

+478
-113
lines changed

3 files changed

+478
-113
lines changed

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

+84-22
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.inferred.freebuilder.processor.PropertyCodeGenerator.Config;
4242
import org.inferred.freebuilder.processor.excerpt.CheckedList;
4343
import org.inferred.freebuilder.processor.util.Block;
44+
import org.inferred.freebuilder.processor.util.Excerpt;
4445
import org.inferred.freebuilder.processor.util.Excerpts;
4546
import org.inferred.freebuilder.processor.util.ParameterizedType;
4647
import org.inferred.freebuilder.processor.util.QualifiedName;
@@ -114,11 +115,19 @@ private static boolean hasAddMethodOverride(Config config, TypeMirror keyType) {
114115

115116
@Override
116117
public void addBuilderFieldDeclaration(SourceBuilder code) {
117-
code.addLine("private final %1$s<%2$s> %3$s = new %1$s%4$s();",
118-
ArrayList.class,
119-
elementType,
120-
property.getName(),
121-
diamondOperator(elementType));
118+
if (code.feature(GUAVA).isAvailable()) {
119+
code.addLine("private %s<%s> %s = %s.of();",
120+
List.class,
121+
elementType,
122+
property.getName(),
123+
ImmutableList.class);
124+
} else {
125+
code.addLine("private final %1$s<%2$s> %3$s = new %1$s%4$s();",
126+
ArrayList.class,
127+
elementType,
128+
property.getName(),
129+
diamondOperator(elementType));
130+
}
122131
}
123132

124133
@Override
@@ -144,6 +153,14 @@ private void addAdd(SourceBuilder code, Metadata metadata) {
144153
code.addLine(" */")
145154
.addLine("public %s %s(%s element) {",
146155
metadata.getBuilder(), addMethod(property), unboxedType.or(elementType));
156+
if (code.feature(GUAVA).isAvailable()) {
157+
code.addLine(" if (this.%s instanceof %s) {", property.getName(), ImmutableList.class)
158+
.addLine(" this.%1$s = new %2$s%3$s(this.%1$s);",
159+
property.getName(),
160+
ArrayList.class,
161+
diamondOperator(elementType))
162+
.addLine(" }");
163+
}
147164
if (unboxedType.isPresent()) {
148165
code.addLine(" this.%s.add(element);", property.getName());
149166
} else {
@@ -199,12 +216,25 @@ private void addAddAll(SourceBuilder code, Metadata metadata) {
199216
metadata.getBuilder(),
200217
addAllMethod(property),
201218
Iterable.class,
202-
elementType)
203-
.addLine(" if (elements instanceof %s) {", Collection.class)
204-
.addLine(" %1$s.ensureCapacity(%1$s.size() + ((%2$s<?>) elements).size());",
205-
property.getName(), Collection.class)
206-
.addLine(" }")
207-
.add(Excerpts.forEach(unboxedType.or(elementType), "elements", addMethod(property)))
219+
elementType);
220+
code.addLine(" if (elements instanceof %s) {", Collection.class)
221+
.addLine(" int elementsSize = ((%s<?>) elements).size();", Collection.class);
222+
if (code.feature(GUAVA).isAvailable()) {
223+
code.addLine(" if (elementsSize != 0) {")
224+
.addLine(" if (%s instanceof %s) {", property.getName(), ImmutableList.class)
225+
.addLine(" %1$s = new %2$s%3$s(%1$s);",
226+
property.getName(), ArrayList.class, diamondOperator(elementType))
227+
.addLine(" }")
228+
.add(" ((%s<?>) %s)", ArrayList.class, property.getName());
229+
} else {
230+
code.add(" %s", property.getName());
231+
}
232+
code.add(".ensureCapacity(%s.size() + elementsSize);%n", property.getName())
233+
.addLine(" }");
234+
if (code.feature(GUAVA).isAvailable()) {
235+
code.addLine(" }");
236+
}
237+
code.add(Excerpts.forEach(unboxedType.or(elementType), "elements", addMethod(property)))
208238
.addLine(" return (%s) this;", metadata.getBuilder())
209239
.addLine("}");
210240
}
@@ -233,6 +263,14 @@ private void addMutate(SourceBuilder code, Metadata metadata) {
233263
consumer.getQualifiedName(),
234264
List.class,
235265
elementType);
266+
if (code.feature(GUAVA).isAvailable()) {
267+
code.addLine(" if (this.%s instanceof %s) {", property.getName(), ImmutableList.class)
268+
.addLine(" this.%1$s = new %2$s%3$s(this.%1$s);",
269+
property.getName(),
270+
ArrayList.class,
271+
diamondOperator(elementType))
272+
.addLine(" }");
273+
}
236274
if (overridesAddMethod) {
237275
code.addLine(" mutator.accept(new CheckedList<>(%s, this::%s));",
238276
property.getName(), addMethod(property));
@@ -253,9 +291,17 @@ private void addClear(SourceBuilder code, Metadata metadata) {
253291
.addLine(" *")
254292
.addLine(" * @return this {@code %s} object", metadata.getBuilder().getSimpleName())
255293
.addLine(" */")
256-
.addLine("public %s %s() {", metadata.getBuilder(), clearMethod(property))
257-
.addLine(" this.%s.clear();", property.getName())
258-
.addLine(" return (%s) this;", metadata.getBuilder())
294+
.addLine("public %s %s() {", metadata.getBuilder(), clearMethod(property));
295+
if (code.feature(GUAVA).isAvailable()) {
296+
code.addLine(" if (%s instanceof %s) {", property.getName(), ImmutableList.class)
297+
.addLine(" %s = %s.of();", property.getName(), ImmutableList.class)
298+
.addLine(" } else {");
299+
}
300+
code.addLine(" %s.clear();", property.getName());
301+
if (code.feature(GUAVA).isAvailable()) {
302+
code.addLine(" }");
303+
}
304+
code.addLine(" return (%s) this;", metadata.getBuilder())
259305
.addLine("}");
260306
}
261307

@@ -266,8 +312,14 @@ private void addGetter(SourceBuilder code, Metadata metadata) {
266312
.addLine(" * %s.", metadata.getType().javadocNoArgMethodLink(property.getGetterName()))
267313
.addLine(" * Changes to this builder will be reflected in the view.")
268314
.addLine(" */")
269-
.addLine("public %s<%s> %s() {", List.class, elementType, getter(property))
270-
.addLine(" return %s.unmodifiableList(%s);", Collections.class, property.getName())
315+
.addLine("public %s<%s> %s() {", List.class, elementType, getter(property));
316+
if (code.feature(GUAVA).isAvailable()) {
317+
code.addLine(" if (%s instanceof %s) {", property.getName(), ImmutableList.class)
318+
.addLine(" %1$s = new %2$s%3$s(%1$s);",
319+
property.getName(), ArrayList.class, diamondOperator(elementType))
320+
.addLine(" }");
321+
}
322+
code.addLine(" return %s.unmodifiableList(%s);", Collections.class, property.getName())
271323
.addLine("}");
272324
}
273325

@@ -284,16 +336,26 @@ public void addFinalFieldAssignment(SourceBuilder code, String finalField, Strin
284336

285337
@Override
286338
public void addMergeFromValue(Block code, String value) {
339+
if (code.feature(GUAVA).isAvailable()) {
340+
code.addLine("if (%s instanceof %s && %s == %s.<%s>of()) {",
341+
value,
342+
metadata.getValueType(),
343+
property.getName(),
344+
ImmutableList.class,
345+
elementType)
346+
.addLine(" %s = %s.%s();", property.getName(), value, property.getGetterName())
347+
.addLine("} else {");
348+
}
287349
code.addLine("%s(%s.%s());", addAllMethod(property), value, property.getGetterName());
350+
if (code.feature(GUAVA).isAvailable()) {
351+
code.addLine("}");
352+
}
288353
}
289354

290355
@Override
291356
public void addMergeFromBuilder(Block code, String builder) {
292-
code.addLine("%s(((%s) %s).%s);",
293-
addAllMethod(property),
294-
metadata.getGeneratedBuilder(),
295-
builder,
296-
property.getName());
357+
Excerpt base = Declarations.upcastToGeneratedBuilder(code, metadata, builder);
358+
code.addLine("%s(%s.%s);", addAllMethod(property), base, property.getName());
297359
}
298360

299361
@Override
@@ -303,7 +365,7 @@ public void addSetFromResult(SourceBuilder code, String builder, String variable
303365

304366
@Override
305367
public void addClearField(Block code) {
306-
code.addLine("%s.clear();", property.getName());
368+
code.addLine("%s();", clearMethod(property));
307369
}
308370

309371
@Override

0 commit comments

Comments
 (0)