8 Replies Latest reply: Jul 13, 2010 3:03 AM by 843793 RSS

    Full class name

    843793
      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
          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
            It's a sublclass of Visitor from the com.sun.tools.javac.tree package.
            • 3. Re: Full class name
              843793
              Class.getCanonicalName()
              • 4. Re: Full class name
                843793
                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
                  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
                    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
                      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
                        Thank you very much for answer!
                        Too bad it is not possible for anonymous classes.

                        Wisnia.