T6996914a.java revision 913:ca32f2986301
1/*
2 * Copyright (c) 2010, 2011, 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 6996914 7020044
27 * @summary  Diamond inference: problem when accessing protected constructor
28 * @run main T6996914a
29 */
30
31import com.sun.source.util.JavacTask;
32import java.net.URI;
33import java.util.Arrays;
34import javax.tools.Diagnostic;
35import javax.tools.DiagnosticListener;
36import javax.tools.JavaCompiler;
37import javax.tools.JavaFileObject;
38import javax.tools.SimpleJavaFileObject;
39import javax.tools.ToolProvider;
40
41public class T6996914a {
42
43    enum PackageKind {
44        DEFAULT("", ""),
45        A("package a;", "import a.*;");
46
47        String pkgDecl;
48        String importDecl;
49
50        PackageKind(String pkgDecl, String importDecl) {
51            this.pkgDecl = pkgDecl;
52            this.importDecl = importDecl;
53        }
54    }
55
56    enum ConstructorKind {
57        PACKAGE(""),
58        PROTECTED("protected"),
59        PRIVATE("private"),
60        PUBLIC("public");
61
62        String mod;
63
64        ConstructorKind(String mod) {
65            this.mod = mod;
66        }
67    }
68
69    static class FooClass extends SimpleJavaFileObject {
70
71        final static String sourceStub =
72                        "#P\n" +
73                        "public class Foo<X> {\n" +
74                        "  #M Foo() {}\n" +
75                        "}\n";
76
77        String source;
78
79        public FooClass(PackageKind pk, ConstructorKind ck) {
80            super(URI.create("myfo:/" + (pk != PackageKind.DEFAULT ? "a/Foo.java" : "Foo.java")),
81                    JavaFileObject.Kind.SOURCE);
82            source = sourceStub.replace("#P", pk.pkgDecl).replace("#M", ck.mod);
83        }
84
85        @Override
86        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
87            return source;
88        }
89    }
90
91    static class ClientClass extends SimpleJavaFileObject {
92
93        final static String sourceStub =
94                        "#I\n" +
95                        "class Test {\n" +
96                        "  Foo<String> fs = new Foo<>();\n" +
97                        "}\n";
98
99        String source;
100
101        public ClientClass(PackageKind pk) {
102            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
103            source = sourceStub.replace("#I", pk.importDecl);
104        }
105
106        @Override
107        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
108            return source;
109        }
110    }
111
112    public static void main(String... args) throws Exception {
113        for (PackageKind pk : PackageKind.values()) {
114            for (ConstructorKind ck : ConstructorKind.values()) {
115                    compileAndCheck(pk, ck);
116            }
117        }
118    }
119
120    static void compileAndCheck(PackageKind pk, ConstructorKind ck) throws Exception {
121        FooClass foo = new FooClass(pk, ck);
122        ClientClass client = new ClientClass(pk);
123        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
124        ErrorListener el = new ErrorListener();
125        JavacTask ct = (JavacTask)tool.getTask(null, null, el,
126                null, null, Arrays.asList(foo, client));
127        ct.analyze();
128        if (el.errors > 0 == check(pk, ck)) {
129            String msg = el.errors > 0 ?
130                "Error compiling files" :
131                "No error when compiling files";
132            throw new AssertionError(msg + ": \n" + foo.source + "\n" + client.source);
133        }
134    }
135
136    static boolean check(PackageKind pk, ConstructorKind ck) {
137        switch (pk) {
138            case A: return ck == ConstructorKind.PUBLIC;
139            case DEFAULT: return ck != ConstructorKind.PRIVATE;
140            default: throw new AssertionError("Unknown package kind");
141        }
142    }
143
144    /**
145     * DiagnosticListener to count any errors that occur
146     */
147    private static class ErrorListener implements DiagnosticListener<JavaFileObject> {
148
149        public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
150            switch (diagnostic.getKind()) {
151                case ERROR:
152                    errors++;
153            }
154        }
155        int errors;
156    }
157}
158