langtools/test/tools/javac/api/TestGetElement.java
changeset 6590 f745e683da2c
child 30730 d3ce7619db2c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/api/TestGetElement.java	Mon Sep 06 12:55:09 2010 -0700
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6930507
+ * @summary Symbols for anonymous and local classes made too late for use by java tree API
+ */
+
+import java.io.*;
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.*;
+import javax.tools.Diagnostic;
+import static javax.lang.model.util.ElementFilter.*;
+
+import com.sun.source.tree.*;
+import com.sun.source.util.*;
+
+@SupportedOptions({"test", "last"})
+@SupportedAnnotationTypes("*")
+public class TestGetElement extends AbstractProcessor {
+    public static void main(String... args) throws Exception {
+        new TestGetElement().run();
+    }
+
+    public TestGetElement() { }
+
+    public void run() throws Exception {
+        final String testSrc = System.getProperty("test.src");
+        final String testClasses = System.getProperty("test.classes");
+        final String myClassName = getClass().getName();
+        final String mySrc = new File(testSrc, myClassName + ".java").getPath();
+
+        final int NUM_TESTS = 90; // #decls in this source file
+        for (int i = 1; i <= NUM_TESTS; i++) {
+            System.err.println("test " + i);
+            File testDir = new File("test" + i);
+            File classesDir = new File(testDir, "classes");
+            classesDir.mkdirs();
+            String[] args = {
+                "-d", classesDir.getPath(),
+                "-processorpath", testClasses,
+                "-processor", myClassName,
+                "-proc:only",
+                "-Atest=" + i,
+                "-Alast=" + (i == NUM_TESTS),
+                mySrc
+            };
+
+//            System.err.println("compile: " + Arrays.asList(args));
+
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+            int rc = com.sun.tools.javac.Main.compile(args, pw);
+            pw.close();
+            String out = sw.toString();
+            if (out != null)
+                System.err.println(out);
+            if (rc != 0) {
+                System.err.println("compilation failed: rc=" + rc);
+                errors++;
+            }
+        }
+
+        if (errors > 0)
+            throw new Exception(errors + " errors occurred");
+    }
+
+
+    int errors;
+
+    public boolean process(Set<? extends TypeElement> annotations,
+                           RoundEnvironment roundEnvironment)
+    {
+        if (roundEnvironment.processingOver())
+            return true;
+
+        Map<String,String> options = processingEnv.getOptions();
+        int test = Integer.parseInt(options.get("test"));
+        boolean _last = Boolean.parseBoolean(options.get("last"));
+
+        Trees trees = Trees.instance(processingEnv);
+        Scanner scanner = new Scanner(trees, _last);
+        int nelems = 0;
+        for (TypeElement e : typesIn(roundEnvironment.getRootElements())) {
+            nelems += scanner.scan(trees.getPath(e), test);
+        }
+
+        Messager m = processingEnv.getMessager();
+        int EXPECT = 1;
+        if (nelems != EXPECT) {
+            m.printMessage(Diagnostic.Kind.ERROR,
+                    "Unexpected number of elements found: " + nelems + " expected: " + EXPECT);
+        }
+        return true;
+    }
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+        return SourceVersion.latest();
+    }
+
+    class Scanner extends TreePathScanner<Integer,Integer> {
+        final Trees trees;
+        final boolean last;
+        int count;
+
+        Scanner(Trees trees, boolean last) {
+            this.trees = trees;
+            this.last = last;
+        }
+
+        @Override
+        public Integer visitClass(ClassTree tree, Integer test) {
+            return reduce(check(test), super.visitClass(tree, test));
+        }
+
+        @Override
+        public Integer visitMethod(MethodTree tree, Integer test) {
+            return reduce(check(test), super.visitMethod(tree, test));
+        }
+
+        @Override
+        public Integer visitVariable(VariableTree tree, Integer test) {
+            return reduce(check(test), super.visitVariable(tree, test));
+        }
+
+        @Override
+        public Integer reduce(Integer i1, Integer i2) {
+            if (i1 == null || i1.intValue() == 0)
+                return i2;
+            if (i2 == null || i2.intValue() == 0)
+                return i1;
+            return (i1 + i2);
+        }
+
+        int check(int test) {
+            count++;
+
+            if (count != test)
+                return 0;
+
+            TreePath p = getCurrentPath();
+            Element e = trees.getElement(p);
+
+            String text = p.getLeaf().toString().replaceAll("\\s+", " ").trim();
+            int MAXLEN = 40;
+            if (text.length() > MAXLEN)
+                text = text.substring(0, MAXLEN - 3) + "...";
+
+            System.err.println(String.format("%3d: %-" + MAXLEN + "s -- %s",
+                    count, text,
+                    (e == null ? "null" : e.getKind() + " " + e)));
+
+            Messager m = processingEnv.getMessager();
+            if (e == null) {
+                m.printMessage(Diagnostic.Kind.ERROR, "Null element found for " + text);
+                return 0;
+            }
+
+            if (last && !e.getSimpleName().contentEquals("last")) {
+                m.printMessage(Diagnostic.Kind.ERROR, "Unexpected name in last test: "
+                        + e.getSimpleName() + ", expected: last");
+            }
+
+            return 1;
+        }
+    }
+
+    // following are all fodder for the test
+
+    class MemberClass {
+        class NestedMemberClass { }
+    }
+
+    {
+        class InnerClassInInit { }
+        Object o = new Object() { };
+    }
+
+    TestGetElement(TestGetElement unused) {
+        class InnerClassInConstr { }
+        Object o = new Object() { };
+    }
+
+    void m() {
+        class InnerClassInMethod { }
+        Object o = new Object() { };
+
+        class C {
+            class MemberClass {
+                class NestedMemberClass { }
+            }
+
+            {
+                class InnerClassInInit { }
+                Object o = new Object() { };
+            }
+
+            C(Object unused) {
+                class InnerClassInConstr { }
+                Object o = new Object() { };
+            }
+
+            void m() {
+                class InnerClassInMethod { }
+                Object o = new Object() { };
+            }
+        }
+    }
+
+    int last; // this name is verified by the test to make sure that all decls are checked
+}