langtools/test/tools/javac/api/TestGetElement.java
changeset 6590 f745e683da2c
child 30730 d3ce7619db2c
equal deleted inserted replaced
6589:32e0dcb94381 6590:f745e683da2c
       
     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  */
       
    23 
       
    24 /*
       
    25  * @test
       
    26  * @bug 6930507
       
    27  * @summary Symbols for anonymous and local classes made too late for use by java tree API
       
    28  */
       
    29 
       
    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.*;
       
    37 
       
    38 import com.sun.source.tree.*;
       
    39 import com.sun.source.util.*;
       
    40 
       
    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     }
       
    47 
       
    48     public TestGetElement() { }
       
    49 
       
    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();
       
    55 
       
    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             };
       
    71 
       
    72 //            System.err.println("compile: " + Arrays.asList(args));
       
    73 
       
    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         }
       
    86 
       
    87         if (errors > 0)
       
    88             throw new Exception(errors + " errors occurred");
       
    89     }
       
    90 
       
    91 
       
    92     int errors;
       
    93 
       
    94     public boolean process(Set<? extends TypeElement> annotations,
       
    95                            RoundEnvironment roundEnvironment)
       
    96     {
       
    97         if (roundEnvironment.processingOver())
       
    98             return true;
       
    99 
       
   100         Map<String,String> options = processingEnv.getOptions();
       
   101         int test = Integer.parseInt(options.get("test"));
       
   102         boolean _last = Boolean.parseBoolean(options.get("last"));
       
   103 
       
   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         }
       
   110 
       
   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     }
       
   119 
       
   120     @Override
       
   121     public SourceVersion getSupportedSourceVersion() {
       
   122         return SourceVersion.latest();
       
   123     }
       
   124 
       
   125     class Scanner extends TreePathScanner<Integer,Integer> {
       
   126         final Trees trees;
       
   127         final boolean last;
       
   128         int count;
       
   129 
       
   130         Scanner(Trees trees, boolean last) {
       
   131             this.trees = trees;
       
   132             this.last = last;
       
   133         }
       
   134 
       
   135         @Override
       
   136         public Integer visitClass(ClassTree tree, Integer test) {
       
   137             return reduce(check(test), super.visitClass(tree, test));
       
   138         }
       
   139 
       
   140         @Override
       
   141         public Integer visitMethod(MethodTree tree, Integer test) {
       
   142             return reduce(check(test), super.visitMethod(tree, test));
       
   143         }
       
   144 
       
   145         @Override
       
   146         public Integer visitVariable(VariableTree tree, Integer test) {
       
   147             return reduce(check(test), super.visitVariable(tree, test));
       
   148         }
       
   149 
       
   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         }
       
   158 
       
   159         int check(int test) {
       
   160             count++;
       
   161 
       
   162             if (count != test)
       
   163                 return 0;
       
   164 
       
   165             TreePath p = getCurrentPath();
       
   166             Element e = trees.getElement(p);
       
   167 
       
   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) + "...";
       
   172 
       
   173             System.err.println(String.format("%3d: %-" + MAXLEN + "s -- %s",
       
   174                     count, text,
       
   175                     (e == null ? "null" : e.getKind() + " " + e)));
       
   176 
       
   177             Messager m = processingEnv.getMessager();
       
   178             if (e == null) {
       
   179                 m.printMessage(Diagnostic.Kind.ERROR, "Null element found for " + text);
       
   180                 return 0;
       
   181             }
       
   182 
       
   183             if (last && !e.getSimpleName().contentEquals("last")) {
       
   184                 m.printMessage(Diagnostic.Kind.ERROR, "Unexpected name in last test: "
       
   185                         + e.getSimpleName() + ", expected: last");
       
   186             }
       
   187 
       
   188             return 1;
       
   189         }
       
   190     }
       
   191 
       
   192     // following are all fodder for the test
       
   193 
       
   194     class MemberClass {
       
   195         class NestedMemberClass { }
       
   196     }
       
   197 
       
   198     {
       
   199         class InnerClassInInit { }
       
   200         Object o = new Object() { };
       
   201     }
       
   202 
       
   203     TestGetElement(TestGetElement unused) {
       
   204         class InnerClassInConstr { }
       
   205         Object o = new Object() { };
       
   206     }
       
   207 
       
   208     void m() {
       
   209         class InnerClassInMethod { }
       
   210         Object o = new Object() { };
       
   211 
       
   212         class C {
       
   213             class MemberClass {
       
   214                 class NestedMemberClass { }
       
   215             }
       
   216 
       
   217             {
       
   218                 class InnerClassInInit { }
       
   219                 Object o = new Object() { };
       
   220             }
       
   221 
       
   222             C(Object unused) {
       
   223                 class InnerClassInConstr { }
       
   224                 Object o = new Object() { };
       
   225             }
       
   226 
       
   227             void m() {
       
   228                 class InnerClassInMethod { }
       
   229                 Object o = new Object() { };
       
   230             }
       
   231         }
       
   232     }
       
   233 
       
   234     int last; // this name is verified by the test to make sure that all decls are checked
       
   235 }