TestSuperclass.java revision 2687:56f8be952a5c
1/*
2 * Copyright (c) 2011, 2014, 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 */
29
30import java.io.File;
31import java.io.IOException;
32import java.io.PrintWriter;
33import java.io.StringWriter;
34import java.net.URI;
35import java.util.Arrays;
36import javax.tools.JavaCompiler;
37import javax.tools.JavaCompiler.CompilationTask;
38import javax.tools.JavaFileObject;
39import javax.tools.SimpleJavaFileObject;
40import javax.tools.StandardJavaFileManager;
41import javax.tools.StandardLocation;
42import javax.tools.ToolProvider;
43
44public class TestSuperclass {
45    enum ClassKind {
46        CLASS("class"),
47        INTERFACE("interface");
48        ClassKind(String keyword) {
49            this.keyword = keyword;
50        }
51        final String keyword;
52    }
53
54    enum GenericKind {
55        NO(""),
56        YES("<T>");
57        GenericKind(String typarams) {
58            this.typarams = typarams;
59        }
60        final String typarams;
61    }
62
63    enum SuperKind {
64        NONE(null),
65        SUPER("Super");
66        SuperKind(String name) {
67            this.name = name;
68        }
69        String extend() {
70            return (name == null) ? "" : "extends " + name;
71        }
72        String decl(ClassKind ck) {
73            return (name == null) ? "" : ck.keyword + " " + name + " { }";
74        }
75        final String name;
76    }
77
78    public static void main(String... args) throws Exception {
79        JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
80        try (StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null)) {
81            int errors = 0;
82
83            for (ClassKind ck: ClassKind.values()) {
84                for (GenericKind gk: GenericKind.values()) {
85                    for (SuperKind sk: SuperKind.values()) {
86                        errors += new TestSuperclass(ck, gk, sk).run(comp, fm);
87                    }
88                }
89            }
90
91            if (errors > 0)
92                throw new Exception(errors + " errors found");
93        }
94    }
95
96    final ClassKind ck;
97    final GenericKind gk;
98    final SuperKind sk;
99
100    TestSuperclass(ClassKind ck, GenericKind gk, SuperKind sk) {
101        this.ck = ck;
102        this.gk = gk;
103        this.sk = sk;
104    }
105
106    int run(JavaCompiler comp, StandardJavaFileManager fm) throws IOException {
107        System.err.println("test: ck:" + ck + " gk:" + gk + " sk:" + sk);
108        File testDir = new File(ck + "-" + gk + "-" + sk);
109        testDir.mkdirs();
110        fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(testDir));
111
112        JavaSource js = new JavaSource();
113        System.err.println(js.getCharContent(false));
114        CompilationTask t = comp.getTask(null, fm, null, null, null, Arrays.asList(js));
115        if (!t.call())
116            throw new Error("compilation failed");
117
118        File testClass = new File(testDir, "Test.class");
119        String out = javap(testClass);
120
121        // Extract class sig from first line of Java source
122        String expect = js.source.replaceAll("(?s)^(.* Test[^{]+?) *\\{.*", "$1");
123
124        // Extract class sig from line from javap output
125        String found = out.replaceAll("(?s).*\n(.* Test[^{]+?) *\\{.*", "$1");
126
127        checkEqual("class signature", expect, found);
128
129        return errors;
130    }
131
132    String javap(File file) {
133        StringWriter sw = new StringWriter();
134        PrintWriter pw = new PrintWriter(sw);
135        String[] args = { file.getPath() };
136        int rc = com.sun.tools.javap.Main.run(args, pw);
137        pw.close();
138        String out = sw.toString();
139        if (!out.isEmpty())
140            System.err.println(out);
141        if (rc != 0)
142            throw new Error("javap failed: rc=" + rc);
143        return out;
144    }
145
146    void checkEqual(String label, String expect, String found) {
147        if (!expect.equals(found))
148            error("Unexpected " + label + " found: '" + found + "', expected: '" + expect + "'");
149    }
150
151    void error(String msg) {
152        System.err.println("Error: " + msg);
153        errors++;
154    }
155
156    int errors;
157
158    class JavaSource extends SimpleJavaFileObject {
159        static final String template =
160                  "#CK Test#GK #EK { }\n"
161                + "#SK\n";
162        final String source;
163
164        public JavaSource() {
165            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
166            source = template
167                    .replace("#CK", ck.keyword)
168                    .replace("#GK", gk.typarams)
169                    .replace("#EK", sk.extend())
170                    .replace("#SK", sk.decl(ck));
171        }
172
173        @Override
174        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
175            return source;
176        }
177    }
178
179}
180