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