test/tools/javac/api/TestGetElement.java

Mon, 06 Sep 2010 12:55:09 -0700

author
jjg
date
Mon, 06 Sep 2010 12:55:09 -0700
changeset 672
ea54372637a5
parent 0
959103a6100f
permissions
-rw-r--r--

6930507: Symbols for anonymous and local classes made too late for use by java tree API
Reviewed-by: mcimadamore

     1 /*
     2  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  */
    24 /*
    25  * @test
    26  * @bug 6930507
    27  * @summary Symbols for anonymous and local classes made too late for use by java tree API
    28  */
    30 import java.io.*;
    31 import java.util.*;
    32 import javax.annotation.processing.*;
    33 import javax.lang.model.SourceVersion;
    34 import javax.lang.model.element.*;
    35 import javax.tools.Diagnostic;
    36 import static javax.lang.model.util.ElementFilter.*;
    38 import com.sun.source.tree.*;
    39 import com.sun.source.util.*;
    41 @SupportedOptions({"test", "last"})
    42 @SupportedAnnotationTypes("*")
    43 public class TestGetElement extends AbstractProcessor {
    44     public static void main(String... args) throws Exception {
    45         new TestGetElement().run();
    46     }
    48     public TestGetElement() { }
    50     public void run() throws Exception {
    51         final String testSrc = System.getProperty("test.src");
    52         final String testClasses = System.getProperty("test.classes");
    53         final String myClassName = getClass().getName();
    54         final String mySrc = new File(testSrc, myClassName + ".java").getPath();
    56         final int NUM_TESTS = 90; // #decls in this source file
    57         for (int i = 1; i <= NUM_TESTS; i++) {
    58             System.err.println("test " + i);
    59             File testDir = new File("test" + i);
    60             File classesDir = new File(testDir, "classes");
    61             classesDir.mkdirs();
    62             String[] args = {
    63                 "-d", classesDir.getPath(),
    64                 "-processorpath", testClasses,
    65                 "-processor", myClassName,
    66                 "-proc:only",
    67                 "-Atest=" + i,
    68                 "-Alast=" + (i == NUM_TESTS),
    69                 mySrc
    70             };
    72 //            System.err.println("compile: " + Arrays.asList(args));
    74             StringWriter sw = new StringWriter();
    75             PrintWriter pw = new PrintWriter(sw);
    76             int rc = com.sun.tools.javac.Main.compile(args, pw);
    77             pw.close();
    78             String out = sw.toString();
    79             if (out != null)
    80                 System.err.println(out);
    81             if (rc != 0) {
    82                 System.err.println("compilation failed: rc=" + rc);
    83                 errors++;
    84             }
    85         }
    87         if (errors > 0)
    88             throw new Exception(errors + " errors occurred");
    89     }
    92     int errors;
    94     public boolean process(Set<? extends TypeElement> annotations,
    95                            RoundEnvironment roundEnvironment)
    96     {
    97         if (roundEnvironment.processingOver())
    98             return true;
   100         Map<String,String> options = processingEnv.getOptions();
   101         int test = Integer.parseInt(options.get("test"));
   102         boolean _last = Boolean.parseBoolean(options.get("last"));
   104         Trees trees = Trees.instance(processingEnv);
   105         Scanner scanner = new Scanner(trees, _last);
   106         int nelems = 0;
   107         for (TypeElement e : typesIn(roundEnvironment.getRootElements())) {
   108             nelems += scanner.scan(trees.getPath(e), test);
   109         }
   111         Messager m = processingEnv.getMessager();
   112         int EXPECT = 1;
   113         if (nelems != EXPECT) {
   114             m.printMessage(Diagnostic.Kind.ERROR,
   115                     "Unexpected number of elements found: " + nelems + " expected: " + EXPECT);
   116         }
   117         return true;
   118     }
   120     @Override
   121     public SourceVersion getSupportedSourceVersion() {
   122         return SourceVersion.latest();
   123     }
   125     class Scanner extends TreePathScanner<Integer,Integer> {
   126         final Trees trees;
   127         final boolean last;
   128         int count;
   130         Scanner(Trees trees, boolean last) {
   131             this.trees = trees;
   132             this.last = last;
   133         }
   135         @Override
   136         public Integer visitClass(ClassTree tree, Integer test) {
   137             return reduce(check(test), super.visitClass(tree, test));
   138         }
   140         @Override
   141         public Integer visitMethod(MethodTree tree, Integer test) {
   142             return reduce(check(test), super.visitMethod(tree, test));
   143         }
   145         @Override
   146         public Integer visitVariable(VariableTree tree, Integer test) {
   147             return reduce(check(test), super.visitVariable(tree, test));
   148         }
   150         @Override
   151         public Integer reduce(Integer i1, Integer i2) {
   152             if (i1 == null || i1.intValue() == 0)
   153                 return i2;
   154             if (i2 == null || i2.intValue() == 0)
   155                 return i1;
   156             return (i1 + i2);
   157         }
   159         int check(int test) {
   160             count++;
   162             if (count != test)
   163                 return 0;
   165             TreePath p = getCurrentPath();
   166             Element e = trees.getElement(p);
   168             String text = p.getLeaf().toString().replaceAll("\\s+", " ").trim();
   169             int MAXLEN = 40;
   170             if (text.length() > MAXLEN)
   171                 text = text.substring(0, MAXLEN - 3) + "...";
   173             System.err.println(String.format("%3d: %-" + MAXLEN + "s -- %s",
   174                     count, text,
   175                     (e == null ? "null" : e.getKind() + " " + e)));
   177             Messager m = processingEnv.getMessager();
   178             if (e == null) {
   179                 m.printMessage(Diagnostic.Kind.ERROR, "Null element found for " + text);
   180                 return 0;
   181             }
   183             if (last && !e.getSimpleName().contentEquals("last")) {
   184                 m.printMessage(Diagnostic.Kind.ERROR, "Unexpected name in last test: "
   185                         + e.getSimpleName() + ", expected: last");
   186             }
   188             return 1;
   189         }
   190     }
   192     // following are all fodder for the test
   194     class MemberClass {
   195         class NestedMemberClass { }
   196     }
   198     {
   199         class InnerClassInInit { }
   200         Object o = new Object() { };
   201     }
   203     TestGetElement(TestGetElement unused) {
   204         class InnerClassInConstr { }
   205         Object o = new Object() { };
   206     }
   208     void m() {
   209         class InnerClassInMethod { }
   210         Object o = new Object() { };
   212         class C {
   213             class MemberClass {
   214                 class NestedMemberClass { }
   215             }
   217             {
   218                 class InnerClassInInit { }
   219                 Object o = new Object() { };
   220             }
   222             C(Object unused) {
   223                 class InnerClassInConstr { }
   224                 Object o = new Object() { };
   225             }
   227             void m() {
   228                 class InnerClassInMethod { }
   229                 Object o = new Object() { };
   230             }
   231         }
   232     }
   234     int last; // this name is verified by the test to make sure that all decls are checked
   235 }

mercurial