656N/A/*
656N/A * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
656N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
656N/A *
656N/A * This code is free software; you can redistribute it and/or modify it
656N/A * under the terms of the GNU General Public License version 2 only, as
656N/A * published by the Free Software Foundation.
656N/A *
656N/A * This code is distributed in the hope that it will be useful, but WITHOUT
656N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
656N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
656N/A * version 2 for more details (a copy is included in the LICENSE file that
656N/A * accompanied this code).
656N/A *
656N/A * You should have received a copy of the GNU General Public License version
656N/A * 2 along with this work; if not, write to the Free Software Foundation,
656N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
656N/A *
656N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
656N/A * or visit www.oracle.com if you need additional information or have any
656N/A * questions.
656N/A */
656N/A
656N/A/*
656N/A * @test
656N/A * @bug 6960424
656N/A * @summary new option -Xpkginfo for better control of when package-info.class is generated
656N/A */
656N/A
656N/Aimport java.io.*;
656N/Aimport java.util.*;
656N/A
656N/Apublic class TestPkgInfo {
656N/A enum OptKind {
656N/A NONE(null),
656N/A ALWAYS("-Xpkginfo:always"),
656N/A NONEMPTY("-Xpkginfo:nonempty"),
656N/A LEGACY("-Xpkginfo:legacy");
656N/A OptKind(String opt) { this.opt = opt; }
656N/A final String opt;
656N/A };
656N/A
656N/A public static void main(String... args) throws Exception {
656N/A new TestPkgInfo().run(args);
656N/A }
656N/A
656N/A public void run(String... args) throws Exception {
656N/A boolean[] booleanValues = { false, true };
656N/A for (OptKind ok: OptKind.values()) {
656N/A for (boolean sr: booleanValues) {
656N/A for (boolean cr: booleanValues) {
656N/A for (boolean rr: booleanValues) {
656N/A try {
656N/A test(ok, sr, cr, rr);
656N/A } catch (Exception e) {
656N/A error("Exception: " + e);
656N/A }
656N/A if (errors > 0) throw new AssertionError();
656N/A }
656N/A }
656N/A }
656N/A }
656N/A
656N/A if (errors > 0)
656N/A throw new Exception(errors + " errors occurred");
656N/A }
656N/A
656N/A void test(OptKind ok, boolean sr, boolean cr, boolean rr) throws Exception {
656N/A count++;
656N/A System.err.println("Test " + count + ": ok:" + ok + " sr:" + sr + " cr:" + cr + " rr:" + rr);
656N/A
656N/A StringBuilder sb = new StringBuilder();
656N/A
656N/A // create annotated package statement with all combinations of retention policy
656N/A if (sr) sb.append("@SR\n");
656N/A if (cr) sb.append("@CR\n");
656N/A if (rr) sb.append("@RR\n");
656N/A sb.append("package p;\n");
656N/A sb.append("\n");
656N/A
656N/A sb.append("import java.lang.annotation.*;\n");
656N/A sb.append("@Retention(RetentionPolicy.SOURCE) @interface SR { }\n");
656N/A sb.append("@Retention(RetentionPolicy.CLASS) @interface CR { }\n");
656N/A sb.append("@Retention(RetentionPolicy.RUNTIME) @interface RR { }\n");
656N/A
656N/A // test specific tmp directory
656N/A File tmpDir = new File("tmp.test" + count);
656N/A File classesDir = new File(tmpDir, "classes");
656N/A classesDir.mkdirs();
656N/A File pkginfo_java = new File(new File(tmpDir, "src"), "package-info.java");
656N/A writeFile(pkginfo_java, sb.toString());
656N/A
656N/A // build up list of options and files to be compiled
656N/A List<String> opts = new ArrayList<String>();
656N/A List<File> files = new ArrayList<File>();
656N/A
656N/A opts.add("-d");
656N/A opts.add(classesDir.getPath());
656N/A if (ok.opt != null)
656N/A opts.add(ok.opt);
656N/A //opts.add("-verbose");
656N/A files.add(pkginfo_java);
656N/A
656N/A compile(opts, files);
656N/A
656N/A File pkginfo_class = new File(new File(classesDir, "p"), "package-info.class");
656N/A boolean exists = pkginfo_class.exists();
656N/A
656N/A boolean expected;
656N/A switch (ok) {
656N/A case ALWAYS:
656N/A expected = true;
656N/A break;
656N/A
656N/A case LEGACY:
656N/A case NONE:
656N/A expected = (sr || cr || rr ); // any annotation
656N/A break;
656N/A
656N/A case NONEMPTY:
656N/A expected = (cr || rr ); // any annotation in class file
656N/A break;
656N/A
656N/A default:
656N/A throw new IllegalStateException();
656N/A }
656N/A
656N/A if (exists && !expected)
656N/A error("package-info.class found but not expected");
656N/A if (!exists && expected)
656N/A error("package-info.class expected but not found");
656N/A }
656N/A
656N/A /** Compile files with options provided. */
656N/A void compile(List<String> opts, List<File> files) throws Exception {
656N/A System.err.println("javac: " + opts + " " + files);
656N/A List<String> args = new ArrayList<String>();
656N/A args.addAll(opts);
656N/A for (File f: files)
656N/A args.add(f.getPath());
656N/A StringWriter sw = new StringWriter();
656N/A PrintWriter pw = new PrintWriter(sw);
656N/A int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw);
656N/A pw.flush();
656N/A if (sw.getBuffer().length() > 0)
656N/A System.err.println(sw.toString());
656N/A if (rc != 0)
656N/A throw new Exception("compilation failed: rc=" + rc);
656N/A }
656N/A
656N/A /** Write a file with a given body. */
656N/A void writeFile(File f, String body) throws Exception {
656N/A if (f.getParentFile() != null)
656N/A f.getParentFile().mkdirs();
656N/A Writer out = new FileWriter(f);
656N/A try {
656N/A out.write(body);
656N/A } finally {
656N/A out.close();
656N/A }
656N/A }
656N/A
656N/A /** Report an error. */
656N/A void error(String msg) {
656N/A System.err.println("Error: " + msg);
656N/A errors++;
656N/A }
656N/A
656N/A /** Test case counter. */
656N/A int count;
656N/A
656N/A /** Number of errors found. */
656N/A int errors;
656N/A}