This discussion is archived
8 Replies Latest reply: Jul 13, 2010 1:03 AM by 843793 RSS

Full class name

843793 Newbie
Currently Being Moderated
Hi.

I am creating my first processor in Java 6 that is using custom TreeTranslator to do some metaprogramming.
The problem is that I can not obtain full class name (only Foo instead of some.package.Foo) of visited class.
Is it possible to achieve that during annotation processing?
Some workaround would be to get list of imported class (don't now how to do this too, visitImport does nothing),
or to somehow use reflection from processor (helpless again).

I'll apprecieate any help or suggestions.
Wisnia
  • 1. Re: Full class name
    608410 Newbie
    Currently Being Moderated
    I do not recognize the "TreeTranslator" type from any of the APIs this forum discusses. What is the package name of TreeTranslator?

    Bruce
  • 2. Re: Full class name
    843793 Newbie
    Currently Being Moderated
    It's a sublclass of Visitor from the com.sun.tools.javac.tree package.
  • 3. Re: Full class name
    843793 Newbie
    Currently Being Moderated
    Class.getCanonicalName()
  • 4. Re: Full class name
    843793 Newbie
    Currently Being Moderated
    The problem is I can not get the java.lang.Class object of visited class.

    Here's a fragment of processor...
    public boolean process(Set<? extends TypeElement> annotations,
                   RoundEnvironment roundEnv) {
              
              if (!roundEnv.processingOver()) {     
                   Set<? extends Element> elements = roundEnv.getRootElements();
                   for (Element each : elements) {
                        JCTree tree = (JCTree) trees.getTree(each);
                        TreeTranslator visitor = new TestVisitor();
                        tree.accept(visitor);
                   }
               
              } 
              return false;
         }
     
    and here's the fragment of visitor
              @Override
              public void visitNewClass(JCNewClass c) {
                   System.out.println("##NEW CLASS##");
                   System.out.println(c);
                   System.out.println("NAME_"+c.clazz);
                   System.out.println("######");
                   super.visitNewClass(c);
              }
    The c.clazz does not return java.lang.Class but com.sun.tools.javac.tree.JCTree.JCIdent object with simple name (Foo instead of some.package.Foo).

    Wisnia.
  • 5. Re: Full class name
    843793 Newbie
    Currently Being Moderated
    Instead of
                   
    Set<? extends Element> elements = roundEnv.getRootElements();
    for (Element each : elements) {
         JCTree tree = (JCTree) trees.getTree(each);
         TreeTranslator visitor = new TestVisitor();
         tree.accept(visitor);
    }
    use something like
                   
    Set<? extends TypeElement> typeElements =
        javax.lang.model.util.ElementFilter.typesIn(roundEnv.getRootElements());
    for (TypeElement each : typeElements) {
         Name name = each.getQualifiedName();
          ...
    }
  • 6. Re: Full class name
    843793 Newbie
    Currently Being Moderated
    Thank you j.d.darcy but your code example is only correct for top level classes and I am looking for way to receive names of all classes appearing inside of top level class.

    In example for this class:
    package some.packag;
    
    import some.other.packag.Bar
    import some.other.packag.Baz
    
    public class Foo {
         
         public void match() {
              Bar b = new Bar();
              // other code...
         }
    }
    Your solution would return some.packag.Foo, but my goal is to receive some.other.packag.Bar (new class in match() method).
    Do you know if this(or workarounds described in first post) is even possible in Java 6 (i can switch to some early java 7 build if necessary)?

    Thank you for your time.
    Wisnia
  • 7. Re: Full class name
    843793 Newbie
    Currently Being Moderated
    wisnia1 wrote:
    Thank you j.d.darcy but your code example is only correct for top level classes and I am looking for way to receive names of all classes appearing inside of top level class.

    In example for this class:
    package some.packag;
    
    import some.other.packag.Bar
    import some.other.packag.Baz
    
    public class Foo {
         
         public void match() {
              Bar b = new Bar();
              // other code...
         }
    }
    Your solution would return some.packag.Foo, but my goal is to receive some.other.packag.Bar (new class in match() method).
    Do you know if this(or workarounds described in first post) is even possible in Java 6 (i can switch to some early java 7 build if necessary)?
    Using the tree API, you can map from a tree to an Element like this
    Element element = trees.getElement(trees.getPath(compilationUnit, node));
    Once an element is in hand, it can be visited to verify it is a TypeElement (or whatever it actually is) and the appropriate methods called on it.

    Code that does this sort of conversion is included in the TestAnonSourceNames.java; see for example

    http://hg.openjdk.java.net/jdk7/tl/langtools/file/d2b7ecf33b35/test/tools/javac/processing/model/element/

    Note that currently in javac, conversion of trees for anonymous classes into Elements results in a null.
  • 8. Re: Full class name
    843793 Newbie
    Currently Being Moderated
    Thank you very much for answer!
    Too bad it is not possible for anonymous classes.

    Wisnia.