Skip to content

Commit e97d1f0

Browse files
eamonnmcmanusnick-someone
authored andcommitted
When checking builder setter parameters, use the final type. The final type is the type after type-variable substitution. Report this type in error messages, since it may not be obvious.
(See AutoValueNotEclipseTest for an example of the problem this is fixing.) Fix CompileWithEclipseTest so that it actually does exclude AutoValueNotEclipseTest.java from the compilation, as intended. Move the existing test within that file into AutoValueTest.java, since apparently the Eclipse bug it was provoking has been fixed. Add the test for the bug being fixed here into AutoValueNotEclipseTest.java, because it hits another Eclipse bug. Fixes #802. RELNOTES=Fixed an issue with type checking of setter parameters in the presence of inheritance and generics. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=287580372
1 parent 2e91aaf commit e97d1f0

File tree

4 files changed

+56
-30
lines changed

4 files changed

+56
-30
lines changed

value/src/it/functional/src/test/java/com/google/auto/value/AutoValueNotEclipseTest.java

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
*/
1616
package com.google.auto.value;
1717

18-
import static com.google.common.truth.Truth.assertThat;
18+
import static com.google.common.truth.Truth8.assertThat;
1919

20-
import com.google.common.collect.ImmutableList;
20+
import java.util.Optional;
21+
import javax.annotation.Nullable;
2122
import org.junit.Test;
2223
import org.junit.runner.RunWith;
2324
import org.junit.runners.JUnit4;
@@ -29,37 +30,36 @@
2930
*/
3031
@RunWith(JUnit4.class)
3132
public class AutoValueNotEclipseTest {
32-
interface ImmutableListOf<T> {
33-
ImmutableList<T> list();
33+
// This produced the following error with JDT 4.6:
34+
// Internal compiler error: java.lang.Exception: java.lang.IllegalArgumentException: element
35+
// public abstract B setOptional(T) is not a member of the containing type
36+
// com.google.auto.value.AutoValueTest.ConcreteOptional.Builder nor any of its superclasses at
37+
// org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.handleProcessor(RoundDispatcher.java:169)
38+
interface AbstractOptional<T> {
39+
Optional<T> optional();
40+
41+
interface Builder<T, B extends Builder<T, B>> {
42+
B setOptional(@Nullable T t);
43+
}
3444
}
3545

36-
// This provoked the following with the Eclipse compiler:
37-
// java.lang.NullPointerException
38-
// at org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding.readableName(ParameterizedTypeBinding.java:1021)
39-
// at org.eclipse.jdt.internal.compiler.apt.model.DeclaredTypeImpl.toString(DeclaredTypeImpl.java:118)
40-
// at java.lang.String.valueOf(String.java:2996)
41-
// at java.lang.StringBuilder.append(StringBuilder.java:131)
42-
// at org.eclipse.jdt.internal.compiler.apt.model.TypesImpl.asMemberOf(TypesImpl.java:130)
43-
// at com.google.auto.value.processor.EclipseHack.methodReturnType(EclipseHack.java:124)
44-
// at com.google.auto.value.processor.TypeVariables.lambda$rewriteReturnTypes$1(TypeVariables.java:106)
4546
@AutoValue
46-
abstract static class PropertyBuilderInheritsType implements ImmutableListOf<String> {
47+
abstract static class ConcreteOptional implements AbstractOptional<String> {
4748
static Builder builder() {
48-
return new AutoValue_AutoValueNotEclipseTest_PropertyBuilderInheritsType.Builder();
49+
return new AutoValue_AutoValueNotEclipseTest_ConcreteOptional.Builder();
4950
}
5051

5152
@AutoValue.Builder
52-
abstract static class Builder {
53-
abstract ImmutableList.Builder<String> listBuilder();
54-
abstract PropertyBuilderInheritsType build();
53+
interface Builder extends AbstractOptional.Builder<String, Builder> {
54+
ConcreteOptional build();
5555
}
5656
}
5757

5858
@Test
59-
public void propertyBuilderInheritsType() {
60-
PropertyBuilderInheritsType.Builder builder = PropertyBuilderInheritsType.builder();
61-
builder.listBuilder().add("foo", "bar");
62-
PropertyBuilderInheritsType x = builder.build();
63-
assertThat(x.list()).containsExactly("foo", "bar").inOrder();
59+
public void genericOptionalOfNullable() {
60+
ConcreteOptional empty = ConcreteOptional.builder().build();
61+
assertThat(empty.optional()).isEmpty();
62+
ConcreteOptional notEmpty = ConcreteOptional.builder().setOptional("foo").build();
63+
assertThat(notEmpty.optional()).hasValue("foo");
6464
}
6565
}

value/src/it/functional/src/test/java/com/google/auto/value/AutoValueTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2160,6 +2160,31 @@ public void testBuilderWithPropertyBuilders() {
21602160
}
21612161
}
21622162

2163+
interface ImmutableListOf<T> {
2164+
ImmutableList<T> list();
2165+
}
2166+
2167+
@AutoValue
2168+
abstract static class PropertyBuilderInheritsType implements ImmutableListOf<String> {
2169+
static Builder builder() {
2170+
return new AutoValue_AutoValueTest_PropertyBuilderInheritsType.Builder();
2171+
}
2172+
2173+
@AutoValue.Builder
2174+
abstract static class Builder {
2175+
abstract ImmutableList.Builder<String> listBuilder();
2176+
abstract PropertyBuilderInheritsType build();
2177+
}
2178+
}
2179+
2180+
@Test
2181+
public void propertyBuilderInheritsType() {
2182+
PropertyBuilderInheritsType.Builder builder = PropertyBuilderInheritsType.builder();
2183+
builder.listBuilder().add("foo", "bar");
2184+
PropertyBuilderInheritsType x = builder.build();
2185+
assertThat(x.list()).containsExactly("foo", "bar").inOrder();
2186+
}
2187+
21632188
@AutoValue
21642189
public abstract static class BuilderWithExoticPropertyBuilders<
21652190
K extends Number, V extends Comparable<K>> {

value/src/main/java/com/google/auto/value/processor/BuilderMethodClassifier.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ private Optional<Function<String, String>> getSetterFunction(
434434
// Parameter type is not equal to property type, but might be convertible with copyOf.
435435
ImmutableList<ExecutableElement> copyOfMethods = copyOfMethods(targetType, setter);
436436
if (!copyOfMethods.isEmpty()) {
437-
return getConvertingSetterFunction(copyOfMethods, valueGetter, setter);
437+
return getConvertingSetterFunction(copyOfMethods, valueGetter, setter, parameterType);
438438
}
439439
String error =
440440
String.format(
@@ -452,9 +452,9 @@ private Optional<Function<String, String>> getSetterFunction(
452452
private Optional<Function<String, String>> getConvertingSetterFunction(
453453
ImmutableList<ExecutableElement> copyOfMethods,
454454
ExecutableElement valueGetter,
455-
ExecutableElement setter) {
455+
ExecutableElement setter,
456+
TypeMirror parameterType) {
456457
DeclaredType targetType = MoreTypes.asDeclared(getterToPropertyType.get(valueGetter));
457-
TypeMirror parameterType = setter.getParameters().get(0).asType();
458458
for (ExecutableElement copyOfMethod : copyOfMethods) {
459459
Optional<Function<String, String>> function =
460460
getConvertingSetterFunction(copyOfMethod, targetType, parameterType);
@@ -465,8 +465,9 @@ private Optional<Function<String, String>> getConvertingSetterFunction(
465465
String targetTypeSimpleName = targetType.asElement().getSimpleName().toString();
466466
String error =
467467
String.format(
468-
"Parameter type of setter method should be %s to match getter %s.%s, or it should be a "
469-
+ "type that can be passed to %s.%s to produce %s",
468+
"Parameter type %s of setter method should be %s to match getter %s.%s,"
469+
+ " or it should be a type that can be passed to %s.%s to produce %s",
470+
parameterType,
470471
targetType,
471472
autoValueClass,
472473
valueGetter.getSimpleName(),

value/src/test/java/com/google/auto/value/processor/AutoValueCompilationTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,7 +1599,7 @@ public void autoValueBuilderWrongTypeSetterWithCopyOf() {
15991599
.compile(javaFileObject);
16001600
assertThat(compilation)
16011601
.hadErrorContaining(
1602-
"Parameter type of setter method should be "
1602+
"Parameter type java.lang.String of setter method should be "
16031603
+ "com.google.common.collect.ImmutableList<java.lang.String> to match getter "
16041604
+ "foo.bar.Baz.blam, or it should be a type that can be passed to "
16051605
+ "ImmutableList.copyOf")
@@ -1636,7 +1636,7 @@ public void autoValueBuilderWrongTypeSetterWithCopyOfGenericallyWrong() {
16361636
.compile(javaFileObject);
16371637
assertThat(compilation)
16381638
.hadErrorContaining(
1639-
"Parameter type of setter method should be "
1639+
"Parameter type java.util.Collection<java.lang.Integer> of setter method should be "
16401640
+ "com.google.common.collect.ImmutableList<java.lang.String> to match getter "
16411641
+ "foo.bar.Baz.blam, or it should be a type that can be passed to "
16421642
+ "ImmutableList.copyOf to produce "

0 commit comments

Comments
 (0)