langtools/test/tools/javac/TestPkgInfo.java
changeset 6575 ae1798028008
child 19488 3d9b2d67f71f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TestPkgInfo.java	Wed Aug 25 11:40:25 2010 -0700
@@ -0,0 +1,174 @@
+/*
+ * 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 6960424
+ * @summary new option -Xpkginfo for better control of when package-info.class is generated
+ */
+
+import java.io.*;
+import java.util.*;
+
+public class TestPkgInfo {
+    enum OptKind {
+        NONE(null),
+        ALWAYS("-Xpkginfo:always"),
+        NONEMPTY("-Xpkginfo:nonempty"),
+        LEGACY("-Xpkginfo:legacy");
+        OptKind(String opt) { this.opt = opt; }
+        final String opt;
+    };
+
+    public static void main(String... args) throws Exception {
+        new TestPkgInfo().run(args);
+    }
+
+    public void run(String... args) throws Exception {
+        boolean[] booleanValues = { false, true };
+        for (OptKind ok: OptKind.values()) {
+            for (boolean sr: booleanValues) {
+                for (boolean cr: booleanValues) {
+                    for (boolean rr: booleanValues) {
+                        try {
+                            test(ok, sr, cr, rr);
+                        } catch (Exception e) {
+                            error("Exception: " + e);
+                        }
+                        if (errors > 0) throw new AssertionError();
+                    }
+                }
+            }
+        }
+
+        if (errors > 0)
+            throw new Exception(errors + " errors occurred");
+    }
+
+    void test(OptKind ok, boolean sr, boolean cr, boolean rr) throws Exception {
+        count++;
+        System.err.println("Test " + count + ": ok:" + ok + " sr:" + sr + " cr:" + cr + " rr:" + rr);
+
+        StringBuilder sb = new StringBuilder();
+
+        // create annotated package statement with all combinations of retention policy
+        if (sr) sb.append("@SR\n");
+        if (cr) sb.append("@CR\n");
+        if (rr) sb.append("@RR\n");
+        sb.append("package p;\n");
+        sb.append("\n");
+
+        sb.append("import java.lang.annotation.*;\n");
+        sb.append("@Retention(RetentionPolicy.SOURCE)  @interface SR { }\n");
+        sb.append("@Retention(RetentionPolicy.CLASS)   @interface CR { }\n");
+        sb.append("@Retention(RetentionPolicy.RUNTIME) @interface RR { }\n");
+
+        // test specific tmp directory
+        File tmpDir = new File("tmp.test" + count);
+        File classesDir = new File(tmpDir, "classes");
+        classesDir.mkdirs();
+        File pkginfo_java = new File(new File(tmpDir, "src"), "package-info.java");
+        writeFile(pkginfo_java, sb.toString());
+
+        // build up list of options and files to be compiled
+        List<String> opts = new ArrayList<String>();
+        List<File> files = new ArrayList<File>();
+
+        opts.add("-d");
+        opts.add(classesDir.getPath());
+        if (ok.opt != null)
+            opts.add(ok.opt);
+        //opts.add("-verbose");
+        files.add(pkginfo_java);
+
+        compile(opts, files);
+
+        File pkginfo_class = new File(new File(classesDir, "p"), "package-info.class");
+        boolean exists = pkginfo_class.exists();
+
+        boolean expected;
+        switch (ok) {
+            case ALWAYS:
+                expected = true;
+                break;
+
+            case LEGACY:
+            case NONE:
+                expected = (sr || cr || rr ); // any annotation
+                break;
+
+            case NONEMPTY:
+                expected = (cr || rr ); // any annotation in class file
+                break;
+
+            default:
+                throw new IllegalStateException();
+        }
+
+        if (exists && !expected)
+            error("package-info.class found but not expected");
+        if (!exists && expected)
+            error("package-info.class expected but not found");
+    }
+
+    /** Compile files with options provided. */
+    void compile(List<String> opts, List<File> files) throws Exception {
+        System.err.println("javac: " + opts + " " + files);
+        List<String> args = new ArrayList<String>();
+        args.addAll(opts);
+        for (File f: files)
+            args.add(f.getPath());
+        StringWriter sw = new StringWriter();
+        PrintWriter pw = new PrintWriter(sw);
+        int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw);
+        pw.flush();
+        if (sw.getBuffer().length() > 0)
+            System.err.println(sw.toString());
+        if (rc != 0)
+            throw new Exception("compilation failed: rc=" + rc);
+    }
+
+    /** Write a file with a given body. */
+    void writeFile(File f, String body) throws Exception {
+        if (f.getParentFile() != null)
+            f.getParentFile().mkdirs();
+        Writer out = new FileWriter(f);
+        try {
+            out.write(body);
+        } finally {
+            out.close();
+        }
+    }
+
+    /** Report an error. */
+    void error(String msg) {
+        System.err.println("Error: " + msg);
+        errors++;
+    }
+
+    /** Test case counter. */
+    int count;
+
+    /** Number of errors found. */
+    int errors;
+}