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

Commit

Permalink
Simplify TypeVariableName.get(TypeVariable)
Browse files Browse the repository at this point in the history
There's actually no need to deal with intersection types as type mirrors,
we can just go down to the TypeParameterElement and directly get its
bounds.
  • Loading branch information
tbroyer committed Jul 11, 2015
1 parent 5a37c2a commit ff68284
Showing 1 changed file with 7 additions and 50 deletions.
57 changes: 7 additions & 50 deletions src/main/java/com/squareup/javapoet/TypeVariableName.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -81,8 +76,13 @@ public static TypeVariableName get(String name, Type... bounds) {

/** Returns type variable equivalent to {@code mirror}. */
public static TypeVariableName get(javax.lang.model.type.TypeVariable mirror) {
String name = mirror.asElement().getSimpleName().toString();
List<? extends TypeMirror> boundsMirrors = typeVariableBounds(mirror);
return get((TypeParameterElement) mirror.asElement());
}

/** Returns type variable equivalent to {@code element}. */
public static TypeVariableName get(TypeParameterElement element) {
String name = element.getSimpleName().toString();
List<? extends TypeMirror> boundsMirrors = element.getBounds();

List<TypeName> boundsTypeNames = new ArrayList<>();
for (TypeMirror typeMirror : boundsMirrors) {
Expand All @@ -92,49 +92,6 @@ public static TypeVariableName get(javax.lang.model.type.TypeVariable mirror) {
return new TypeVariableName(name, boundsTypeNames);
}

/**
* 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.
*/
@SuppressWarnings("unchecked") // Gross things in support of Java 7 and Java 8.
private static List<? extends TypeMirror> 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<? extends TypeMirror>) 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<TypeMirror> result = new ArrayList<>();
result.add(upperBoundElement.getSuperclass());
result.addAll(upperBoundElement.getInterfaces());
return result;
}
} else if (upperBound.getKind() == TypeKind.TYPEVAR) {
// Workaround for intersection types in Eclipse:
// Eclipse returns an equivalent TypeVariable for intersection types
// (wrapping the same internal TypeVariableBinding).
TypeParameterElement upperBoundElement =
(TypeParameterElement) ((javax.lang.model.type.TypeVariable) upperBound).asElement();
if (upperBoundElement.equals(typeVariable.asElement())) {
return upperBoundElement.getBounds();
}
}

return Collections.singletonList(upperBound);
}

/** Returns type variable equivalent to {@code type}. */
public static TypeVariableName get(TypeVariable<?> type) {
return new TypeVariableName(type.getName(), TypeName.list(type.getBounds()));
Expand Down

0 comments on commit ff68284

Please sign in to comment.