From eca5711c71e6dc97fc7552fc007e5fc2ce3d6c81 Mon Sep 17 00:00:00 2001 From: marcosb Date: Mon, 6 Jul 2015 16:05:58 -0600 Subject: [PATCH 1/6] Fix bug when using javapoet with Eclipse compiler For the following code: public interface Interface1 {} public interface Interface 2 {} public T myMethod(T input) {} a code generator (javax.annotation.processing.Processor) in eclipse will have a TypeVariable for the return type T instead of a DeclaredType. This results in a stack overflow exception, because the return value of Collections.singletonList(upperBound) ends up returning a list containing, in essence, the input parameter. --- src/main/java/com/squareup/javapoet/TypeVariableName.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/com/squareup/javapoet/TypeVariableName.java b/src/main/java/com/squareup/javapoet/TypeVariableName.java index 910f61f42..3fb747b80 100644 --- a/src/main/java/com/squareup/javapoet/TypeVariableName.java +++ b/src/main/java/com/squareup/javapoet/TypeVariableName.java @@ -25,6 +25,7 @@ import java.util.List; import javax.lang.model.element.NestingKind; import javax.lang.model.element.TypeElement; +import javax.lang.model.element.TypeParameterElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; @@ -120,6 +121,12 @@ private static List typeVariableBounds( result.addAll(upperBoundElement.getInterfaces()); return result; } + } else if (upperBound.getKind() == TypeKind.TYPEVAR) { + TypeParameterElement upperBoundElement = + (TypeParameterElement) ((javax.lang.model.type.TypeVariable) upperBound).asElement(); + List result = new ArrayList<>(); + result.addAll(upperBoundElement.getBounds()); + return result; } return Collections.singletonList(upperBound); From 803ba8d1e07cb313a181260bbd11b22c2aebdfe4 Mon Sep 17 00:00:00 2001 From: marcosb Date: Tue, 7 Jul 2015 10:29:27 -0600 Subject: [PATCH 2/6] Broke a test Fixes TypesTest#getTypeVariableTypeMirror --- src/main/java/com/squareup/javapoet/TypeVariableName.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/squareup/javapoet/TypeVariableName.java b/src/main/java/com/squareup/javapoet/TypeVariableName.java index 3fb747b80..7acc9aa8a 100644 --- a/src/main/java/com/squareup/javapoet/TypeVariableName.java +++ b/src/main/java/com/squareup/javapoet/TypeVariableName.java @@ -124,9 +124,11 @@ private static List typeVariableBounds( } else if (upperBound.getKind() == TypeKind.TYPEVAR) { TypeParameterElement upperBoundElement = (TypeParameterElement) ((javax.lang.model.type.TypeVariable) upperBound).asElement(); - List result = new ArrayList<>(); - result.addAll(upperBoundElement.getBounds()); - return result; + if (upperBoundElement.getBounds().size() > 1) { + List result = new ArrayList<>(); + result.addAll(upperBoundElement.getBounds()); + return result; + } } return Collections.singletonList(upperBound); From ec0d96dc78d4062886ca30d03622978f7df03ef1 Mon Sep 17 00:00:00 2001 From: marcosb Date: Tue, 7 Jul 2015 16:16:50 -0600 Subject: [PATCH 3/6] Remove unnecessary list copy Did a copy-paste from TypeKind.DECLARED and missed that there's no need to re-create a list here. --- src/main/java/com/squareup/javapoet/TypeVariableName.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/squareup/javapoet/TypeVariableName.java b/src/main/java/com/squareup/javapoet/TypeVariableName.java index 7acc9aa8a..47990897f 100644 --- a/src/main/java/com/squareup/javapoet/TypeVariableName.java +++ b/src/main/java/com/squareup/javapoet/TypeVariableName.java @@ -125,9 +125,7 @@ private static List typeVariableBounds( TypeParameterElement upperBoundElement = (TypeParameterElement) ((javax.lang.model.type.TypeVariable) upperBound).asElement(); if (upperBoundElement.getBounds().size() > 1) { - List result = new ArrayList<>(); - result.addAll(upperBoundElement.getBounds()); - return result; + return upperBoundElement.getBounds(); } } From 17d0bc75375a6f613919a021381b834c47e81474 Mon Sep 17 00:00:00 2001 From: marcosb Date: Fri, 10 Jul 2015 11:15:14 -0600 Subject: [PATCH 4/6] Re-thinking type variable bounds If TypeParameterElement#getBounds does the trick, why complicate it? This works both in eclipse as well as javac. --- .../squareup/javapoet/TypeVariableName.java | 34 ++----------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/squareup/javapoet/TypeVariableName.java b/src/main/java/com/squareup/javapoet/TypeVariableName.java index 47990897f..0b558450d 100644 --- a/src/main/java/com/squareup/javapoet/TypeVariableName.java +++ b/src/main/java/com/squareup/javapoet/TypeVariableName.java @@ -97,39 +97,11 @@ public static TypeVariableName get(javax.lang.model.type.TypeVariable mirror) { * is made gnarly by the need to unpack Java 8's new IntersectionType with reflection. We don't * have that type in Java 7, and {@link TypeVariable}'s array of bounds is sufficient anyway. */ - @SuppressWarnings("unchecked") // Gross things in support of Java 7 and Java 8. private static List typeVariableBounds( javax.lang.model.type.TypeVariable typeVariable) { - TypeMirror upperBound = typeVariable.getUpperBound(); - - // On Java 8, unwrap an intersection type into its component bounds. - if ("INTERSECTION".equals(upperBound.getKind().name())) { - try { - Method method = upperBound.getClass().getMethod("getBounds"); - return (List) method.invoke(upperBound); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - // On Java 7, intersection types exist but without explicit API. Use a (clumsy) heuristic. - if (upperBound.getKind() == TypeKind.DECLARED) { - TypeElement upperBoundElement = (TypeElement) ((DeclaredType) upperBound).asElement(); - if (upperBoundElement.getNestingKind() == NestingKind.ANONYMOUS) { - List result = new ArrayList<>(); - result.add(upperBoundElement.getSuperclass()); - result.addAll(upperBoundElement.getInterfaces()); - return result; - } - } else if (upperBound.getKind() == TypeKind.TYPEVAR) { - TypeParameterElement upperBoundElement = - (TypeParameterElement) ((javax.lang.model.type.TypeVariable) upperBound).asElement(); - if (upperBoundElement.getBounds().size() > 1) { - return upperBoundElement.getBounds(); - } - } - - return Collections.singletonList(upperBound); + TypeParameterElement upperBoundElement = + (TypeParameterElement) ((javax.lang.model.type.TypeVariable) typeVariable).asElement(); + return upperBoundElement.getBounds(); } /** Returns type variable equivalent to {@code type}. */ From 28786777c43fe5fa39ecdf0ed77c1d17bec5ef84 Mon Sep 17 00:00:00 2001 From: marcosb Date: Fri, 10 Jul 2015 11:20:15 -0600 Subject: [PATCH 5/6] Fix compile errors from unused imports --- src/main/java/com/squareup/javapoet/TypeVariableName.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/com/squareup/javapoet/TypeVariableName.java b/src/main/java/com/squareup/javapoet/TypeVariableName.java index 0b558450d..ef5daffe5 100644 --- a/src/main/java/com/squareup/javapoet/TypeVariableName.java +++ b/src/main/java/com/squareup/javapoet/TypeVariableName.java @@ -16,18 +16,13 @@ package com.squareup.javapoet; import java.io.IOException; -import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import javax.lang.model.element.NestingKind; -import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeParameterElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import static com.squareup.javapoet.Util.checkArgument; From f1c0fc9898589ed7845b2f849d8b55e3dd2fb3e2 Mon Sep 17 00:00:00 2001 From: marcosb Date: Fri, 10 Jul 2015 11:22:59 -0600 Subject: [PATCH 6/6] Update javadoc --- src/main/java/com/squareup/javapoet/TypeVariableName.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/squareup/javapoet/TypeVariableName.java b/src/main/java/com/squareup/javapoet/TypeVariableName.java index ef5daffe5..e6e8874ba 100644 --- a/src/main/java/com/squareup/javapoet/TypeVariableName.java +++ b/src/main/java/com/squareup/javapoet/TypeVariableName.java @@ -88,9 +88,7 @@ public static TypeVariableName get(javax.lang.model.type.TypeVariable mirror) { } /** - * Returns a list of type mirrors representing the unpacked bounds of {@code typeVariable}. This - * is made gnarly by the need to unpack Java 8's new IntersectionType with reflection. We don't - * have that type in Java 7, and {@link TypeVariable}'s array of bounds is sufficient anyway. + * Returns a list of type mirrors representing the unpacked bounds of {@code typeVariable}. */ private static List typeVariableBounds( javax.lang.model.type.TypeVariable typeVariable) {