duke@1: /* duke@1: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@1: * duke@1: * This code is free software; you can redistribute it and/or modify it duke@1: * under the terms of the GNU General Public License version 2 only, as duke@1: * published by the Free Software Foundation. duke@1: * duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@1: * version 2 for more details (a copy is included in the LICENSE file that duke@1: * accompanied this code). duke@1: * duke@1: * You should have received a copy of the GNU General Public License version duke@1: * 2 along with this work; if not, write to the Free Software Foundation, duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@1: * duke@1: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@1: * CA 95054 USA or visit www.sun.com if you need additional information or duke@1: * have any questions. duke@1: */ duke@1: duke@1: /** duke@1: * @test duke@1: * @bug 6341866 duke@1: * @summary Source files loaded from source path are not subject to annotation processing duke@1: * @build Anno T6341866 duke@1: * @run main T6341866 duke@1: */ duke@1: duke@1: import java.io.*; duke@1: import java.util.*; duke@1: import javax.annotation.processing.*; duke@1: import javax.tools.*; duke@1: duke@1: /** duke@1: * For each of a number of implicit compilation scenarios, duke@1: * and for each of a set of annotation processing scenarios, duke@1: * verify that a class file is generated, or not, for an duke@1: * implicitly compiled source file and that the correct duke@1: * warning message is given for implicitly compiled files duke@1: * when annotation processing. duke@1: */ duke@1: public class T6341866 { duke@1: static final String testSrc = System.getProperty("test.src", "."); duke@1: static final String testClasses = System.getProperty("test.classes", "."); duke@1: static final File a_java = new File(testSrc, "A.java"); duke@1: static final File a_class = new File("A.class"); duke@1: static final File b_java = new File(testSrc, "B.java"); duke@1: static final File b_class = new File("B.class"); duke@1: static final File processorServices = services(Processor.class); duke@1: duke@1: enum ImplicitType { duke@1: NONE(null), // don't use implicit compilation duke@1: OPT_UNSET(null), // implicit compilation, but no -implicit option duke@1: OPT_NONE("-implicit:none"), // implicit compilation wiith -implicit:none duke@1: OPT_CLASS("-implicit:class"); // implicit compilation wiith -implicit:class duke@1: duke@1: ImplicitType(String opt) { duke@1: this.opt = opt; duke@1: } duke@1: final String opt; duke@1: }; duke@1: duke@1: enum AnnoType { duke@1: NONE, // no annotation processing duke@1: SERVICE, // implicit annotation processing, via ServiceLoader duke@1: SPECIFY // explicit annotation processing duke@1: }; duke@1: duke@1: duke@1: public static void main(String ... args) throws Exception { duke@1: boolean ok = true; duke@1: duke@1: // iterate over all combinations duke@1: for (ImplicitType implicitType: EnumSet.allOf(ImplicitType.class)) { duke@1: for (AnnoType annoType: EnumSet.allOf(AnnoType.class)) { duke@1: ok &= test(implicitType, annoType); duke@1: } duke@1: } duke@1: duke@1: if (!ok) duke@1: throw new AssertionError("test failed"); duke@1: } duke@1: duke@1: /** duke@1: * Verify that a class file is generated, or not, for an implicitly compiled source file, duke@1: * and that the correct warning message is given for implicitly compiled files when annotation processing. duke@1: */ duke@1: static boolean test(ImplicitType implicitType, AnnoType annoType) throws IOException { duke@1: System.err.println("test implicit=" + implicitType + " anno=" + annoType); duke@1: duke@1: // ensure clean start duke@1: a_class.delete(); duke@1: b_class.delete(); duke@1: processorServices.delete(); duke@1: duke@1: List opts = new ArrayList(); duke@1: opts.addAll(Arrays.asList("-d", ".", "-sourcepath", testSrc, "-classpath", testClasses)); duke@1: if (implicitType.opt != null) duke@1: opts.add(implicitType.opt); duke@1: duke@1: switch (annoType) { duke@1: case SERVICE: duke@1: createProcessorServices(Anno.class.getName()); duke@1: break; duke@1: case SPECIFY: duke@1: opts.addAll(Arrays.asList("-processor", Anno.class.getName())); duke@1: break; duke@1: } duke@1: duke@1: duke@1: JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); duke@1: MyDiagListener dl = new MyDiagListener(); duke@1: StandardJavaFileManager fm = javac.getStandardFileManager(dl, null, null); duke@1: duke@1: // Note: class A references class B, so compile A if we want implicit compilation duke@1: File file = (implicitType != ImplicitType.NONE) ? a_java : b_java; duke@1: Iterable files = fm.getJavaFileObjects(file); duke@1: duke@1: //System.err.println("compile: " + opts + " " + files); duke@1: duke@1: boolean ok = javac.getTask(null, fm, dl, opts, null, files).call(); duke@1: if (!ok) { duke@1: error("compilation failed"); duke@1: return false; duke@1: } duke@1: duke@1: // check implicit compilation results if necessary duke@1: if (implicitType != ImplicitType.NONE) { duke@1: boolean expectClass = (implicitType != ImplicitType.OPT_NONE); duke@1: if (b_class.exists() != expectClass) { duke@1: if (b_class.exists()) duke@1: error("B implicitly compiled unexpectedly"); duke@1: else duke@1: error("B not impliictly compiled"); duke@1: return false; duke@1: } duke@1: } duke@1: duke@1: // check message key results duke@1: String expectKey = null; duke@1: if (implicitType == ImplicitType.OPT_UNSET) { duke@1: switch (annoType) { duke@1: case SERVICE: duke@1: expectKey = "compiler.warn.proc.use.proc.or.implicit"; duke@1: break; duke@1: case SPECIFY: duke@1: expectKey = "compiler.warn.proc.use.implicit"; duke@1: break; duke@1: } duke@1: } duke@1: duke@1: if (expectKey == null) { duke@1: if (dl.diagCodes.size() != 0) { duke@1: error("no diagnostics expected"); duke@1: return false; duke@1: } duke@1: } else { duke@1: if (!(dl.diagCodes.size() == 1 && dl.diagCodes.get(0).equals(expectKey))) { duke@1: error("unexpected diagnostics generated"); duke@1: return false; duke@1: } duke@1: } duke@1: duke@1: return true; duke@1: } duke@1: duke@1: static void createProcessorServices(String name) throws IOException { duke@1: processorServices.getParentFile().mkdirs(); duke@1: duke@1: BufferedWriter out = new BufferedWriter(new FileWriter(processorServices)); duke@1: out.write(name); duke@1: out.newLine(); duke@1: out.close(); duke@1: } duke@1: duke@1: static class MyDiagListener implements DiagnosticListener { duke@1: public void report(Diagnostic d) { duke@1: diagCodes.add(d.getCode()); duke@1: System.err.println(d); duke@1: } duke@1: duke@1: List diagCodes = new ArrayList(); duke@1: } duke@1: duke@1: static void error(String msg) { jjg@11: System.err.println("ERROR: " + msg); duke@1: } duke@1: duke@1: static File services(Class service) { duke@1: String[] dirs = { testClasses, "META-INF", "services" }; duke@1: File dir = null; duke@1: for (String d: dirs) duke@1: dir = (dir == null ? new File(d) : new File(dir, d)); duke@1: duke@1: return new File(dir, service.getName()); duke@1: } duke@1: }