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