Top Description Fields Constructors Methods
com.google.auto.value.processor

pack-priv Class EclipseHack

extends Object
Class Inheritance
Static Imports
java.util.stream.Collectors.toList

Hacks needed to work around various bugs and incompatibilities in Eclipse's implementation of annotation processing.
Author
Éamonn McManus

Field Summary

Modifier and TypeField and Description
private final javax.lang.model.util.Elements
private final javax.lang.model.util.Types

Constructor Summary

AccessConstructor and Description
pack-priv
EclipseHack(javax.annotation.processing.ProcessingEnvironment processingEnv)

pack-priv
EclipseHack(javax.lang.model.util.Elements elementUtils, javax.lang.model.util.Types typeUtils)

Method Summary

Modifier and TypeMethod and Description
pack-priv static javax.lang.model.type.TypeMirror
getEnclosingType(javax.lang.model.type.DeclaredType type)

Returns the enclosing type of type, if type is an inner class.

pack-priv javax.lang.model.type.TypeMirror
methodReturnType(javax.lang.model.element.ExecutableElement method, javax.lang.model.type.DeclaredType in)

pack-priv ImmutableMap<javax.lang.model.element.ExecutableElement, javax.lang.model.type.TypeMirror>
methodReturnTypes(Set<javax.lang.model.element.ExecutableElement> methods, javax.lang.model.type.DeclaredType in)

Returns a map containing the real return types of the given methods, knowing that they appear in the given type.

private Map<javax.lang.model.element.Name, javax.lang.model.element.ExecutableElement>
noArgMethodsIn(javax.lang.model.type.DeclaredType in)

Constructs a map from name to method of the no-argument methods in the given type.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

elementUtilsback to summary
private final javax.lang.model.util.Elements elementUtils
typeUtilsback to summary
private final javax.lang.model.util.Types typeUtils

Constructor Detail

EclipseHackback to summary
pack-priv EclipseHack(javax.annotation.processing.ProcessingEnvironment processingEnv)
EclipseHackback to summary
pack-priv EclipseHack(javax.lang.model.util.Elements elementUtils, javax.lang.model.util.Types typeUtils)

Method Detail

getEnclosingTypeback to summary
pack-priv static javax.lang.model.type.TypeMirror getEnclosingType(javax.lang.model.type.DeclaredType type)

Returns the enclosing type of type, if type is an inner class. Otherwise returns a NoType. This is what DeclaredType#getEnclosingType() is supposed to do. However, some versions of Eclipse have a bug where, for example, asking for the enclosing type of PrimitiveIterator.OfInt will return PrimitiveIterator<T, T_CONS> rather than plain PrimitiveIterator, as if OfInt were an inner class rather than a static one. This would lead us to write a reference to OfInt as PrimitiveIterator<T, T_CONS>.OfInt, which would obviously break. We attempt to avert this by detecting that:

  • there is an enclosing type that is a DeclaredType, which should mean that type is an inner class;
  • we are in the Eclipse compiler;
  • the type arguments of the purported enclosing type are all type variables with the same names as the corresponding type parameters.

If all these conditions are met, we assume we're hitting the Eclipse bug, and we return no enclosing type instead. That does mean that in the unlikely event where we really do have an inner class of an instantiation of the outer class with type arguments that happen to be type variables with the same names as the corresponding parameters, we will do the wrong thing on Eclipse. But doing the wrong thing in that case is better than doing the wrong thing in the usual case.

methodReturnTypeback to summary
pack-priv javax.lang.model.type.TypeMirror methodReturnType(javax.lang.model.element.ExecutableElement method, javax.lang.model.type.DeclaredType in)
methodReturnTypesback to summary
pack-priv ImmutableMap<javax.lang.model.element.ExecutableElement, javax.lang.model.type.TypeMirror> methodReturnTypes(Set<javax.lang.model.element.ExecutableElement> methods, javax.lang.model.type.DeclaredType in)

Returns a map containing the real return types of the given methods, knowing that they appear in the given type. This means that if the given type is say StringIterator implements Iterator<String> then we want the next() method to map to String, rather than the T that it returns as inherited from Iterator<T>. This method is in EclipseHack because if it weren't for this Eclipse bug it would be trivial. Unfortunately, versions of Eclipse up to at least 4.5 have a bug where the Types#asMemberOf method throws IllegalArgumentException if given a method that is inherited from an interface. Fortunately, Eclipse's implementation of Elements#getAllMembers does the type substitution that asMemberOf would have done. But javac's implementation doesn't. So we try the way that would work if Eclipse weren't buggy, and only if we get IllegalArgumentException do we use getAllMembers.

noArgMethodsInback to summary
private Map<javax.lang.model.element.Name, javax.lang.model.element.ExecutableElement> noArgMethodsIn(javax.lang.model.type.DeclaredType in)

Constructs a map from name to method of the no-argument methods in the given type. We need this because an ExecutableElement returned by Elements#getAllMembers will not compare equal to the original ExecutableElement if getAllMembers substituted type parameters, as it does in Eclipse.