javax.lang.model: How do I get the type of a field?

I stumbled across this trying to make sense out of the new JDK Doclet hairball. The accepted answer didn't work for me because, well, Doclet has various internal classes that cannot be used. Furthermore, this answer is more akin to "how do I convert TypeMirror to TypeElement"; given the paucity of java.lang.model SO questions+answers, I thought I'd post this anyway.

Here's what I did:

import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;

@Override
public boolean run(DocletEnvironment docEnv) {
    ...        
    elementUtils = docEnv.getElementUtils();
    typeUtils    = docEnv.getTypeUtils();
    ...
}

When you have a TypeElement t that is a class/interface "kind" you can do something like this to go from TypeMirror to TypeElement.

TypeMirror   p = t.getSuperclass();
TypeElement pe = (TypeElement) typeUtils.asElement(p);

I hope this helps someone.


Well, I don't know, it that's the right way to do this.
Would be nice if someone, who actually understands this API, told me.

But well, seams to work.

public class SomeClass {
  private final ProcessingEnvironment pe = /* get it somewhere */;
  private final Types typeUtils = pe.getTypeUtils();

  public TypeElement getExtracted(VariableElement ve) {
    TypeMirror typeMirror = ve.asType();
    Element element = typeUtils.asElement(typeMirror);

    // instanceof implies null-ckeck
    return (element instanceof TypeElement)
        ? (TypeElement)element : null;
  }
}

It seems that the class Types has to be got from current ProcessingEnvironment because some of its internals depend on it, so it's not a usual utility class.