aboutsummaryrefslogtreecommitdiff
path: root/factory
diff options
context:
space:
mode:
authorgsaul <gsaul@google.com>2019-08-15 13:39:20 -0700
committerDavid P. Baker <dpb@google.com>2019-08-19 12:23:56 -0400
commitc35f5c3a7490cff1e307d65c49a4447140d47195 (patch)
treee5c6e3da2919b8af9c9803715ef7eba45bffe270 /factory
parente63019a49c2081c61595c36e499ab244aa82c40b (diff)
downloadauto-c35f5c3a7490cff1e307d65c49a4447140d47195.tar.gz
Prevent stack overflow caused by self referencing types (ex: E extends Enum<E>).
RELNOTES="Prevent stack overflow caused by self referencing types (ex: E extends Enum<E>)." #AutoFactory ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=263631678
Diffstat (limited to 'factory')
-rw-r--r--factory/src/it/functional/src/main/java/com/google/auto/factory/GenericFoo.java19
-rw-r--r--factory/src/it/functional/src/test/java/com/google/auto/factory/DependencyInjectionIntegrationTest.java21
-rw-r--r--factory/src/main/java/com/google/auto/factory/processor/TypeVariables.java49
3 files changed, 62 insertions, 27 deletions
diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/GenericFoo.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/GenericFoo.java
index 94ee8a5b..f7c13b41 100644
--- a/factory/src/it/functional/src/main/java/com/google/auto/factory/GenericFoo.java
+++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/GenericFoo.java
@@ -19,18 +19,24 @@ import java.util.List;
import javax.inject.Provider;
@AutoFactory
-public class GenericFoo<A, B extends List<? extends A>, C> {
+public class GenericFoo<A, B extends List<? extends A>, C, E extends Enum<E>> {
private final A depA;
private final B depB;
private final IntAccessor depDIntAccessor;
private final StringAccessor depDStringAccessor;
+ private final E depE;
- <D extends IntAccessor & StringAccessor> GenericFoo(@Provided Provider<A> depA, B depB, D depD) {
+ <D extends IntAccessor & StringAccessor> GenericFoo(
+ @Provided Provider<A> depA,
+ B depB,
+ D depD,
+ E depE) {
this.depA = depA.get();
this.depB = depB;
this.depDIntAccessor = depD;
this.depDStringAccessor = depD;
+ this.depE = depE;
}
public A getDepA() {
@@ -53,9 +59,18 @@ public class GenericFoo<A, B extends List<? extends A>, C> {
return depDStringAccessor;
}
+ public E getDepE() {
+ return depE;
+ }
+
public interface IntAccessor {}
public interface StringAccessor {}
public interface IntAndStringAccessor extends IntAccessor, StringAccessor {}
+
+ public enum DepE {
+ VALUE_1,
+ VALUE_2
+ }
}
diff --git a/factory/src/it/functional/src/test/java/com/google/auto/factory/DependencyInjectionIntegrationTest.java b/factory/src/it/functional/src/test/java/com/google/auto/factory/DependencyInjectionIntegrationTest.java
index 21ccfbb4..ebd83367 100644
--- a/factory/src/it/functional/src/test/java/com/google/auto/factory/DependencyInjectionIntegrationTest.java
+++ b/factory/src/it/functional/src/test/java/com/google/auto/factory/DependencyInjectionIntegrationTest.java
@@ -2,6 +2,7 @@ package com.google.auto.factory;
import static com.google.common.truth.Truth.assertThat;
+import com.google.auto.factory.GenericFoo.DepE;
import com.google.auto.factory.GenericFoo.IntAndStringAccessor;
import com.google.common.collect.ImmutableList;
import com.google.inject.Guice;
@@ -40,18 +41,19 @@ public class DependencyInjectionIntegrationTest {
public void daggerInjectedGenericFactory() {
GenericFooFactory<Number> genericFooFactory =
DaggerFactoryComponent.create().generatedFactory();
- GenericFoo<Number, ImmutableList<Long>, String> three =
- genericFooFactory.create(ImmutableList.of(3L), INT_AND_STRING_ACCESSOR);
+ GenericFoo<Number, ImmutableList<Long>, String, DepE> three =
+ genericFooFactory.create(ImmutableList.of(3L), INT_AND_STRING_ACCESSOR, DepE.VALUE_1);
ArrayList<Double> intAndStringAccessorArrayList = new ArrayList<>();
intAndStringAccessorArrayList.add(4.0);
- GenericFoo<Number, ArrayList<Double>, Long> four =
- genericFooFactory.create(intAndStringAccessorArrayList, INT_AND_STRING_ACCESSOR);
+ GenericFoo<Number, ArrayList<Double>, Long, DepE> four = genericFooFactory.create(
+ intAndStringAccessorArrayList, INT_AND_STRING_ACCESSOR, DepE.VALUE_2);
assertThat(three.getDepA()).isEqualTo(3);
ImmutableList<Long> unusedLongList = three.getDepB();
assertThat(three.getDepB()).containsExactly(3L);
assertThat(three.getDepDIntAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
assertThat(three.getDepDStringAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
assertThat(three.passThrough("value")).isEqualTo("value");
+ assertThat(three.getDepE()).isEqualTo(DepE.VALUE_1);
assertThat(four.getDepA()).isEqualTo(3);
ArrayList<Double> unusedDoubleList = four.getDepB();
assertThat(four.getDepB()).isInstanceOf(ArrayList.class);
@@ -59,6 +61,7 @@ public class DependencyInjectionIntegrationTest {
assertThat(four.getDepDIntAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
assertThat(four.getDepDStringAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
assertThat(four.passThrough(5L)).isEqualTo(5L);
+ assertThat(four.getDepE()).isEqualTo(DepE.VALUE_2);
}
@Test public void guiceInjectedFactory() {
@@ -85,23 +88,25 @@ public class DependencyInjectionIntegrationTest {
GenericFooFactory<Number> genericFooFactory =
Guice.createInjector(new GuiceModule())
.getInstance(Key.get(new TypeLiteral<GenericFooFactory<Number>>() {}));
- GenericFoo<Number, ImmutableList<Long>, String> three =
- genericFooFactory.create(ImmutableList.of(3L), INT_AND_STRING_ACCESSOR);
+ GenericFoo<Number, ImmutableList<Long>, String, DepE> three =
+ genericFooFactory.create(ImmutableList.of(3L), INT_AND_STRING_ACCESSOR, DepE.VALUE_1);
ArrayList<Double> intAndStringAccessorArrayList = new ArrayList<>();
intAndStringAccessorArrayList.add(4.0);
- GenericFoo<Number, ArrayList<Double>, Long> four =
- genericFooFactory.create(intAndStringAccessorArrayList, INT_AND_STRING_ACCESSOR);
+ GenericFoo<Number, ArrayList<Double>, Long, DepE> four = genericFooFactory.create(
+ intAndStringAccessorArrayList, INT_AND_STRING_ACCESSOR, DepE.VALUE_2);
assertThat(three.getDepA()).isEqualTo(3);
ImmutableList<Long> unusedLongList = three.getDepB();
assertThat(three.getDepB()).containsExactly(3L);
assertThat(three.getDepDIntAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
assertThat(three.getDepDStringAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
assertThat(three.passThrough("value")).isEqualTo("value");
+ assertThat(three.getDepE()).isEqualTo(DepE.VALUE_1);
assertThat(four.getDepA()).isEqualTo(3);
ArrayList<Double> unusedDoubleList = four.getDepB();
assertThat(four.getDepB()).containsExactly(4.0);
assertThat(four.getDepDIntAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
assertThat(four.getDepDStringAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
assertThat(four.passThrough(5L)).isEqualTo(5L);
+ assertThat(four.getDepE()).isEqualTo(DepE.VALUE_2);
}
}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/TypeVariables.java b/factory/src/main/java/com/google/auto/factory/processor/TypeVariables.java
index 35206c29..1f894732 100644
--- a/factory/src/main/java/com/google/auto/factory/processor/TypeVariables.java
+++ b/factory/src/main/java/com/google/auto/factory/processor/TypeVariables.java
@@ -18,6 +18,9 @@ package com.google.auto.factory.processor;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.ImmutableSet;
+import java.util.HashSet;
+import java.util.Set;
+import javax.lang.model.element.Element;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.IntersectionType;
@@ -32,11 +35,12 @@ final class TypeVariables {
static ImmutableSet<TypeVariable> getReferencedTypeVariables(TypeMirror type) {
checkNotNull(type);
- return type.accept(ReferencedTypeVariables.INSTANCE, null);
+ return type.accept(ReferencedTypeVariables.INSTANCE, new HashSet<>());
}
- private static final class ReferencedTypeVariables
- extends SimpleTypeVisitor8<ImmutableSet<TypeVariable>, Void> {
+ private static final class ReferencedTypeVariables extends
+ SimpleTypeVisitor8<ImmutableSet<TypeVariable>, Set<Element>> {
+
private static final ReferencedTypeVariables INSTANCE = new ReferencedTypeVariables();
ReferencedTypeVariables() {
@@ -44,56 +48,67 @@ final class TypeVariables {
}
@Override
- public ImmutableSet<TypeVariable> visitArray(ArrayType t, Void unused) {
- return t.getComponentType().accept(this, unused);
+ public ImmutableSet<TypeVariable> visitArray(ArrayType t, Set<Element> visited) {
+ return t.getComponentType().accept(this, visited);
}
@Override
- public ImmutableSet<TypeVariable> visitDeclared(DeclaredType t, Void unused) {
+ public ImmutableSet<TypeVariable> visitDeclared(
+ DeclaredType t, Set<Element> visited) {
+ if (!visited.add(t.asElement())) {
+ return ImmutableSet.of();
+ }
ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();
for (TypeMirror typeArgument : t.getTypeArguments()) {
- typeVariables.addAll(typeArgument.accept(this, unused));
+ typeVariables.addAll(typeArgument.accept(this, visited));
}
return typeVariables.build();
}
@Override
- public ImmutableSet<TypeVariable> visitTypeVariable(TypeVariable t, Void unused) {
+ public ImmutableSet<TypeVariable> visitTypeVariable(
+ TypeVariable t, Set<Element> visited) {
+ if (!visited.add(t.asElement())) {
+ return ImmutableSet.of();
+ }
ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();
typeVariables.add(t);
- typeVariables.addAll(t.getLowerBound().accept(this, unused));
- typeVariables.addAll(t.getUpperBound().accept(this, unused));
+ typeVariables.addAll(t.getLowerBound().accept(this, visited));
+ typeVariables.addAll(t.getUpperBound().accept(this, visited));
return typeVariables.build();
}
@Override
- public ImmutableSet<TypeVariable> visitUnion(UnionType t, Void unused) {
+ public ImmutableSet<TypeVariable> visitUnion(
+ UnionType t, Set<Element> visited) {
ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();
for (TypeMirror unionType : t.getAlternatives()) {
- typeVariables.addAll(unionType.accept(this, unused));
+ typeVariables.addAll(unionType.accept(this, visited));
}
return typeVariables.build();
}
@Override
- public ImmutableSet<TypeVariable> visitIntersection(IntersectionType t, Void unused) {
+ public ImmutableSet<TypeVariable> visitIntersection(
+ IntersectionType t, Set<Element> visited) {
ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();
for (TypeMirror intersectionType : t.getBounds()) {
- typeVariables.addAll(intersectionType.accept(this, unused));
+ typeVariables.addAll(intersectionType.accept(this, visited));
}
return typeVariables.build();
}
@Override
- public ImmutableSet<TypeVariable> visitWildcard(WildcardType t, Void unused) {
+ public ImmutableSet<TypeVariable> visitWildcard(
+ WildcardType t, Set<Element> visited) {
ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();
TypeMirror extendsBound = t.getExtendsBound();
if (extendsBound != null) {
- typeVariables.addAll(extendsBound.accept(this, unused));
+ typeVariables.addAll(extendsBound.accept(this, visited));
}
TypeMirror superBound = t.getSuperBound();
if (superBound != null) {
- typeVariables.addAll(superBound.accept(this, unused));
+ typeVariables.addAll(superBound.accept(this, visited));
}
return typeVariables.build();
}