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