1 /*
   2  * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 7031005
  27  * @summary javap prints "extends java.lang.Object"
  28  * @modules jdk.compiler
  29  */
  30 
  31 import java.io.File;
  32 import java.io.IOException;
  33 import java.io.PrintWriter;
  34 import java.io.StringWriter;
  35 import java.net.URI;
  36 import java.util.Arrays;
  37 import javax.tools.JavaCompiler;
  38 import javax.tools.JavaCompiler.CompilationTask;
  39 import javax.tools.JavaFileObject;
  40 import javax.tools.SimpleJavaFileObject;
  41 import javax.tools.StandardJavaFileManager;
  42 import javax.tools.StandardLocation;
  43 import javax.tools.ToolProvider;
  44 
  45 public class TestSuperclass {
  46     enum ClassKind {
  47         CLASS("class"),
  48         INTERFACE("interface");
  49         ClassKind(String keyword) {
  50             this.keyword = keyword;
  51         }
  52         final String keyword;
  53     }
  54 
  55     enum GenericKind {
  56         NO(""),
  57         YES("<T>");
  58         GenericKind(String typarams) {
  59             this.typarams = typarams;
  60         }
  61         final String typarams;
  62     }
  63 
  64     enum SuperKind {
  65         NONE(null),
  66         SUPER("Super");
  67         SuperKind(String name) {
  68             this.name = name;
  69         }
  70         String extend() {
  71             return (name == null) ? "" : "extends " + name;
  72         }
  73         String decl(ClassKind ck) {
  74             return (name == null) ? "" : ck.keyword + " " + name + " { }";
  75         }
  76         final String name;
  77     }
  78 
  79     public static void main(String... args) throws Exception {
  80         JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
  81         try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) {
  82             int errors = 0;
  83 
  84             for (ClassKind ck: ClassKind.values()) {
  85                 for (GenericKind gk: GenericKind.values()) {
  86                     for (SuperKind sk: SuperKind.values()) {
  87                         errors += new TestSuperclass(ck, gk, sk).run(comp, fm);
  88                     }
  89                 }
  90             }
  91 
  92             if (errors > 0)
  93                 throw new Exception(errors + " errors found");
  94         }
  95     }
  96 
  97     final ClassKind ck;
  98     final GenericKind gk;
  99     final SuperKind sk;
 100 
 101     TestSuperclass(ClassKind ck, GenericKind gk, SuperKind sk) {
 102         this.ck = ck;
 103         this.gk = gk;
 104         this.sk = sk;
 105     }
 106 
 107     int run(JavaCompiler comp, StandardJavaFileManager fm) throws IOException {
 108         System.err.println("test: ck:" + ck + " gk:" + gk + " sk:" + sk);
 109         File testDir = new File(ck + "-" + gk + "-" + sk);
 110         testDir.mkdirs();
 111         fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(testDir));
 112 
 113         JavaSource js = new JavaSource();
 114         System.err.println(js.getCharContent(false));
 115         CompilationTask t = comp.getTask(null, fm, null, null, null, Arrays.asList(js));
 116         if (!t.call())
 117             throw new Error("compilation failed");
 118 
 119         File testClass = new File(testDir, "Test.class");
 120         String out = javap(testClass);
 121 
 122         // Extract class sig from first line of Java source
 123         String expect = js.source.replaceAll("(?s)^(.* Test[^{]+?) *\\{.*", "$1");
 124 
 125         // Extract class sig from line from javap output
 126         String found = out.replaceAll("(?s).*\n(.* Test[^{]+?) *\\{.*", "$1");
 127 
 128         checkEqual("class signature", expect, found);
 129 
 130         return errors;
 131     }
 132 
 133     String javap(File file) {
 134         StringWriter sw = new StringWriter();
 135         PrintWriter pw = new PrintWriter(sw);
 136         String[] args = { file.getPath() };
 137         int rc = com.sun.tools.javap.Main.run(args, pw);
 138         pw.close();
 139         String out = sw.toString();
 140         if (!out.isEmpty())
 141             System.err.println(out);
 142         if (rc != 0)
 143             throw new Error("javap failed: rc=" + rc);
 144         return out;
 145     }
 146 
 147     void checkEqual(String label, String expect, String found) {
 148         if (!expect.equals(found))
 149             error("Unexpected " + label + " found: '" + found + "', expected: '" + expect + "'");
 150     }
 151 
 152     void error(String msg) {
 153         System.err.println("Error: " + msg);
 154         errors++;
 155     }
 156 
 157     int errors;
 158 
 159     class JavaSource extends SimpleJavaFileObject {
 160         static final String template =
 161                   "#CK Test#GK #EK { }\n"
 162                 + "#SK\n";
 163         final String source;
 164 
 165         public JavaSource() {
 166             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
 167             source = template
 168                     .replace("#CK", ck.keyword)
 169                     .replace("#GK", gk.typarams)
 170                     .replace("#EK", sk.extend())
 171                     .replace("#SK", sk.decl(ck));
 172         }
 173 
 174         @Override
 175         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
 176             return source;
 177         }
 178     }
 179 
 180 }