Skip to content

Commit 7646889

Browse files
eamonnmcmanuscpovirk
authored andcommitted
Ensure that types are substituted correctly in property builders.
The regression test tickles a bug in Eclipse so this change introduces a new place to put tests like that. I don't know how to work around the Eclipse failure, which is a NullPointerException inside Types.asMemberOf. RELNOTES=Property builders now work correctly when their actual return type is different from the corresponding property type because of type variable substitution. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=271621735
1 parent 6dfa04e commit 7646889

File tree

3 files changed

+77
-2
lines changed

3 files changed

+77
-2
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright 2019 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.auto.value;
17+
18+
import static com.google.common.truth.Truth.assertThat;
19+
20+
import com.google.common.collect.ImmutableList;
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
import org.junit.runners.JUnit4;
24+
25+
/**
26+
* Like {@link AutoValueTest}, but with code that doesn't build with at least some versions of
27+
* Eclipse, and should therefore not be included in {@link CompileWithEclipseTest}. (The latter is
28+
* not currently present in the open-source build.)
29+
*/
30+
@RunWith(JUnit4.class)
31+
public class AutoValueNotEclipseTest {
32+
interface ImmutableListOf<T> {
33+
ImmutableList<T> list();
34+
}
35+
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)
45+
@AutoValue
46+
abstract static class PropertyBuilderInheritsType implements ImmutableListOf<String> {
47+
static Builder builder() {
48+
return new AutoValue_AutoValueNotEclipseTest_PropertyBuilderInheritsType.Builder();
49+
}
50+
51+
@AutoValue.Builder
52+
abstract static class Builder {
53+
abstract ImmutableList.Builder<String> listBuilder();
54+
abstract PropertyBuilderInheritsType build();
55+
}
56+
}
57+
58+
@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();
64+
}
65+
}

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,13 @@ private void classifyMethodNoArgs(ExecutableElement method) {
274274
if (getterToPropertyName.containsValue(property)) {
275275
PropertyBuilderClassifier propertyBuilderClassifier =
276276
new PropertyBuilderClassifier(
277-
errorReporter, typeUtils, elementUtils, this, getterToPropertyName, eclipseHack);
277+
errorReporter,
278+
typeUtils,
279+
elementUtils,
280+
this,
281+
getterToPropertyName,
282+
getterToPropertyType,
283+
eclipseHack);
278284
Optional<PropertyBuilder> propertyBuilder =
279285
propertyBuilderClassifier.makePropertyBuilder(method, property);
280286
if (propertyBuilder.isPresent()) {

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.google.auto.common.MoreTypes;
2020
import com.google.common.collect.ImmutableBiMap;
2121
import com.google.common.collect.ImmutableList;
22+
import com.google.common.collect.ImmutableMap;
2223
import com.google.common.collect.ImmutableSet;
2324
import java.util.LinkedHashMap;
2425
import java.util.List;
@@ -52,6 +53,7 @@ class PropertyBuilderClassifier {
5253
private final Elements elementUtils;
5354
private final BuilderMethodClassifier builderMethodClassifier;
5455
private final ImmutableBiMap<ExecutableElement, String> getterToPropertyName;
56+
private final ImmutableMap<ExecutableElement, TypeMirror> getterToPropertyType;
5557
private final EclipseHack eclipseHack;
5658

5759
PropertyBuilderClassifier(
@@ -60,12 +62,14 @@ class PropertyBuilderClassifier {
6062
Elements elementUtils,
6163
BuilderMethodClassifier builderMethodClassifier,
6264
ImmutableBiMap<ExecutableElement, String> getterToPropertyName,
65+
ImmutableMap<ExecutableElement, TypeMirror> getterToPropertyType,
6366
EclipseHack eclipseHack) {
6467
this.errorReporter = errorReporter;
6568
this.typeUtils = typeUtils;
6669
this.elementUtils = elementUtils;
6770
this.builderMethodClassifier = builderMethodClassifier;
6871
this.getterToPropertyName = getterToPropertyName;
72+
this.getterToPropertyType = getterToPropertyType;
6973
this.eclipseHack = eclipseHack;
7074
}
7175

@@ -207,7 +211,7 @@ Optional<PropertyBuilder> makePropertyBuilder(ExecutableElement method, String p
207211
Map<String, ExecutableElement> barBuilderNoArgMethods = noArgMethodsOf(barBuilderTypeElement);
208212

209213
ExecutableElement barGetter = getterToPropertyName.inverse().get(property);
210-
TypeMirror barTypeMirror = barGetter.getReturnType();
214+
TypeMirror barTypeMirror = getterToPropertyType.get(barGetter);
211215
if (barTypeMirror.getKind() != TypeKind.DECLARED) {
212216
errorReporter.reportError(
213217
"Method looks like a property builder, but the type of property "

0 commit comments

Comments
 (0)