test/tools/javac/generics/diamond/7046778/DiamondAndInnerClassTest.java

Fri, 23 Dec 2011 22:30:33 +0000

author
jjg
date
Fri, 23 Dec 2011 22:30:33 +0000
changeset 1169
116f68a5e677
parent 1060
d5f33267a06d
child 1482
954541f13717
permissions
-rw-r--r--

7124605: typos in javac comments
Reviewed-by: ksrini

mcimadamore@1060 1 /*
mcimadamore@1060 2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
mcimadamore@1060 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
mcimadamore@1060 4 *
mcimadamore@1060 5 * This code is free software; you can redistribute it and/or modify it
mcimadamore@1060 6 * under the terms of the GNU General Public License version 2 only, as
mcimadamore@1060 7 * published by the Free Software Foundation.
mcimadamore@1060 8 *
mcimadamore@1060 9 * This code is distributed in the hope that it will be useful, but WITHOUT
mcimadamore@1060 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
mcimadamore@1060 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
mcimadamore@1060 12 * version 2 for more details (a copy is included in the LICENSE file that
mcimadamore@1060 13 * accompanied this code).
mcimadamore@1060 14 *
mcimadamore@1060 15 * You should have received a copy of the GNU General Public License version
mcimadamore@1060 16 * 2 along with this work; if not, write to the Free Software Foundation,
mcimadamore@1060 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
mcimadamore@1060 18 *
mcimadamore@1060 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
mcimadamore@1060 20 * or visit www.oracle.com if you need additional information or have any
mcimadamore@1060 21 * questions.
mcimadamore@1060 22 */
mcimadamore@1060 23
mcimadamore@1060 24 /*
mcimadamore@1060 25 * @test
mcimadamore@1060 26 * @bug 7046778
mcimadamore@1060 27 * @summary Project Coin: problem with diamond and member inner classes
mcimadamore@1060 28 */
mcimadamore@1060 29
mcimadamore@1060 30 import com.sun.source.util.JavacTask;
mcimadamore@1060 31 import java.net.URI;
mcimadamore@1060 32 import java.util.Arrays;
mcimadamore@1060 33 import javax.tools.Diagnostic;
mcimadamore@1060 34 import javax.tools.JavaCompiler;
mcimadamore@1060 35 import javax.tools.JavaFileObject;
mcimadamore@1060 36 import javax.tools.SimpleJavaFileObject;
mcimadamore@1060 37 import javax.tools.StandardJavaFileManager;
mcimadamore@1060 38 import javax.tools.ToolProvider;
mcimadamore@1060 39
mcimadamore@1060 40 public class DiamondAndInnerClassTest {
mcimadamore@1060 41
mcimadamore@1060 42 static int checkCount = 0;
mcimadamore@1060 43
mcimadamore@1060 44 enum TypeArgumentKind {
mcimadamore@1060 45 NONE(""),
mcimadamore@1060 46 STRING("<String>"),
mcimadamore@1060 47 INTEGER("<Integer>"),
mcimadamore@1060 48 DIAMOND("<>");
mcimadamore@1060 49
mcimadamore@1060 50 String typeargStr;
mcimadamore@1060 51
mcimadamore@1060 52 private TypeArgumentKind(String typeargStr) {
mcimadamore@1060 53 this.typeargStr = typeargStr;
mcimadamore@1060 54 }
mcimadamore@1060 55
mcimadamore@1060 56 boolean compatible(TypeArgumentKind that) {
mcimadamore@1060 57 switch (this) {
mcimadamore@1060 58 case NONE: return true;
mcimadamore@1060 59 case STRING: return that != INTEGER;
mcimadamore@1060 60 case INTEGER: return that != STRING;
mcimadamore@1060 61 default: throw new AssertionError("Unexpected decl kind: " + this);
mcimadamore@1060 62 }
mcimadamore@1060 63 }
mcimadamore@1060 64
mcimadamore@1060 65 boolean compatible(ArgumentKind that) {
mcimadamore@1060 66 switch (this) {
mcimadamore@1060 67 case NONE: return true;
mcimadamore@1060 68 case STRING: return that == ArgumentKind.STRING;
mcimadamore@1060 69 case INTEGER: return that == ArgumentKind.INTEGER;
mcimadamore@1060 70 default: throw new AssertionError("Unexpected decl kind: " + this);
mcimadamore@1060 71 }
mcimadamore@1060 72 }
mcimadamore@1060 73 }
mcimadamore@1060 74
mcimadamore@1060 75 enum ArgumentKind {
mcimadamore@1060 76 OBJECT("(Object)null"),
mcimadamore@1060 77 STRING("(String)null"),
mcimadamore@1060 78 INTEGER("(Integer)null");
mcimadamore@1060 79
mcimadamore@1060 80 String argStr;
mcimadamore@1060 81
mcimadamore@1060 82 private ArgumentKind(String argStr) {
mcimadamore@1060 83 this.argStr = argStr;
mcimadamore@1060 84 }
mcimadamore@1060 85 }
mcimadamore@1060 86
mcimadamore@1060 87 enum TypeQualifierArity {
mcimadamore@1060 88 ONE(1, "A1#TA1"),
mcimadamore@1060 89 TWO(2, "A1#TA1.A2#TA2"),
mcimadamore@1060 90 THREE(3, "A1#TA1.A2#TA2.A3#TA3");
mcimadamore@1060 91
mcimadamore@1060 92 int n;
mcimadamore@1060 93 String qualifierStr;
mcimadamore@1060 94
mcimadamore@1060 95 private TypeQualifierArity(int n, String qualifierStr) {
mcimadamore@1060 96 this.n = n;
mcimadamore@1060 97 this.qualifierStr = qualifierStr;
mcimadamore@1060 98 }
mcimadamore@1060 99
mcimadamore@1060 100 String getType(TypeArgumentKind... typeArgumentKinds) {
mcimadamore@1060 101 String res = qualifierStr;
mcimadamore@1060 102 for (int i = 1 ; i <= typeArgumentKinds.length ; i++) {
mcimadamore@1060 103 res = res.replace("#TA" + i, typeArgumentKinds[i-1].typeargStr);
mcimadamore@1060 104 }
mcimadamore@1060 105 return res;
mcimadamore@1060 106 }
mcimadamore@1060 107
mcimadamore@1060 108 boolean matches(InnerClassDeclArity innerClassDeclArity) {
mcimadamore@1060 109 return n ==innerClassDeclArity.n;
mcimadamore@1060 110 }
mcimadamore@1060 111 }
mcimadamore@1060 112
mcimadamore@1060 113 enum InnerClassDeclArity {
mcimadamore@1060 114 ONE(1, "class A1<X> { A1(X x1) { } #B }"),
mcimadamore@1060 115 TWO(2, "class A1<X1> { class A2<X2> { A2(X1 x1, X2 x2) { } #B } }"),
mcimadamore@1060 116 THREE(3, "class A1<X1> { class A2<X2> { class A3<X3> { A3(X1 x1, X2 x2, X3 x3) { } #B } } }");
mcimadamore@1060 117
mcimadamore@1060 118 int n;
mcimadamore@1060 119 String classDeclStr;
mcimadamore@1060 120
mcimadamore@1060 121 private InnerClassDeclArity(int n, String classDeclStr) {
mcimadamore@1060 122 this.n = n;
mcimadamore@1060 123 this.classDeclStr = classDeclStr;
mcimadamore@1060 124 }
mcimadamore@1060 125 }
mcimadamore@1060 126
mcimadamore@1060 127 enum ArgumentListArity {
mcimadamore@1060 128 ONE(1, "(#A1)"),
mcimadamore@1060 129 TWO(2, "(#A1,#A2)"),
mcimadamore@1060 130 THREE(3, "(#A1,#A2,#A3)");
mcimadamore@1060 131
mcimadamore@1060 132 int n;
mcimadamore@1060 133 String argListStr;
mcimadamore@1060 134
mcimadamore@1060 135 private ArgumentListArity(int n, String argListStr) {
mcimadamore@1060 136 this.n = n;
mcimadamore@1060 137 this.argListStr = argListStr;
mcimadamore@1060 138 }
mcimadamore@1060 139
mcimadamore@1060 140 String getArgs(ArgumentKind... argumentKinds) {
mcimadamore@1060 141 String res = argListStr;
mcimadamore@1060 142 for (int i = 1 ; i <= argumentKinds.length ; i++) {
mcimadamore@1060 143 res = res.replace("#A" + i, argumentKinds[i-1].argStr);
mcimadamore@1060 144 }
mcimadamore@1060 145 return res;
mcimadamore@1060 146 }
mcimadamore@1060 147
mcimadamore@1060 148 boolean matches(InnerClassDeclArity innerClassDeclArity) {
mcimadamore@1060 149 return n ==innerClassDeclArity.n;
mcimadamore@1060 150 }
mcimadamore@1060 151 }
mcimadamore@1060 152
mcimadamore@1060 153 public static void main(String... args) throws Exception {
mcimadamore@1060 154
mcimadamore@1060 155 //create default shared JavaCompiler - reused across multiple compilations
mcimadamore@1060 156 JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
mcimadamore@1060 157 StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
mcimadamore@1060 158
mcimadamore@1060 159 for (InnerClassDeclArity innerClassDeclArity : InnerClassDeclArity.values()) {
mcimadamore@1060 160 for (TypeQualifierArity declType : TypeQualifierArity.values()) {
mcimadamore@1060 161 if (!declType.matches(innerClassDeclArity)) continue;
mcimadamore@1060 162 for (TypeQualifierArity newClassType : TypeQualifierArity.values()) {
mcimadamore@1060 163 if (!newClassType.matches(innerClassDeclArity)) continue;
mcimadamore@1060 164 for (ArgumentListArity argList : ArgumentListArity.values()) {
mcimadamore@1060 165 if (!argList.matches(innerClassDeclArity)) continue;
mcimadamore@1060 166 for (TypeArgumentKind taDecl1 : TypeArgumentKind.values()) {
mcimadamore@1060 167 boolean isDeclRaw = taDecl1 == TypeArgumentKind.NONE;
mcimadamore@1060 168 //no diamond on decl site
mcimadamore@1060 169 if (taDecl1 == TypeArgumentKind.DIAMOND) continue;
mcimadamore@1060 170 for (TypeArgumentKind taSite1 : TypeArgumentKind.values()) {
mcimadamore@1060 171 boolean isSiteRaw = taSite1 == TypeArgumentKind.NONE;
mcimadamore@1060 172 //diamond only allowed on the last type qualifier
mcimadamore@1060 173 if (taSite1 == TypeArgumentKind.DIAMOND &&
mcimadamore@1060 174 innerClassDeclArity != InnerClassDeclArity.ONE) continue;
mcimadamore@1060 175 for (ArgumentKind arg1 : ArgumentKind.values()) {
mcimadamore@1060 176 if (innerClassDeclArity == innerClassDeclArity.ONE) {
mcimadamore@1060 177 new DiamondAndInnerClassTest(innerClassDeclArity, declType, newClassType,
mcimadamore@1060 178 argList, new TypeArgumentKind[] {taDecl1},
mcimadamore@1060 179 new TypeArgumentKind[] {taSite1}, new ArgumentKind[] {arg1}).run(comp, fm);
mcimadamore@1060 180 continue;
mcimadamore@1060 181 }
mcimadamore@1060 182 for (TypeArgumentKind taDecl2 : TypeArgumentKind.values()) {
mcimadamore@1060 183 //no rare types
mcimadamore@1060 184 if (isDeclRaw != (taDecl2 == TypeArgumentKind.NONE)) continue;
mcimadamore@1060 185 //no diamond on decl site
mcimadamore@1060 186 if (taDecl2 == TypeArgumentKind.DIAMOND) continue;
mcimadamore@1060 187 for (TypeArgumentKind taSite2 : TypeArgumentKind.values()) {
mcimadamore@1060 188 //no rare types
mcimadamore@1060 189 if (isSiteRaw != (taSite2 == TypeArgumentKind.NONE)) continue;
mcimadamore@1060 190 //diamond only allowed on the last type qualifier
mcimadamore@1060 191 if (taSite2 == TypeArgumentKind.DIAMOND &&
mcimadamore@1060 192 innerClassDeclArity != InnerClassDeclArity.TWO) continue;
mcimadamore@1060 193 for (ArgumentKind arg2 : ArgumentKind.values()) {
mcimadamore@1060 194 if (innerClassDeclArity == innerClassDeclArity.TWO) {
mcimadamore@1060 195 new DiamondAndInnerClassTest(innerClassDeclArity, declType, newClassType,
mcimadamore@1060 196 argList, new TypeArgumentKind[] {taDecl1, taDecl2},
mcimadamore@1060 197 new TypeArgumentKind[] {taSite1, taSite2},
mcimadamore@1060 198 new ArgumentKind[] {arg1, arg2}).run(comp, fm);
mcimadamore@1060 199 continue;
mcimadamore@1060 200 }
mcimadamore@1060 201 for (TypeArgumentKind taDecl3 : TypeArgumentKind.values()) {
mcimadamore@1060 202 //no rare types
mcimadamore@1060 203 if (isDeclRaw != (taDecl3 == TypeArgumentKind.NONE)) continue;
mcimadamore@1060 204 //no diamond on decl site
mcimadamore@1060 205 if (taDecl3 == TypeArgumentKind.DIAMOND) continue;
mcimadamore@1060 206 for (TypeArgumentKind taSite3 : TypeArgumentKind.values()) {
mcimadamore@1060 207 //no rare types
mcimadamore@1060 208 if (isSiteRaw != (taSite3 == TypeArgumentKind.NONE)) continue;
mcimadamore@1060 209 //diamond only allowed on the last type qualifier
mcimadamore@1060 210 if (taSite3 == TypeArgumentKind.DIAMOND &&
mcimadamore@1060 211 innerClassDeclArity != InnerClassDeclArity.THREE) continue;
mcimadamore@1060 212 for (ArgumentKind arg3 : ArgumentKind.values()) {
mcimadamore@1060 213 if (innerClassDeclArity == innerClassDeclArity.THREE) {
mcimadamore@1060 214 new DiamondAndInnerClassTest(innerClassDeclArity, declType, newClassType,
mcimadamore@1060 215 argList, new TypeArgumentKind[] {taDecl1, taDecl2, taDecl3},
mcimadamore@1060 216 new TypeArgumentKind[] {taSite1, taSite2, taSite3},
mcimadamore@1060 217 new ArgumentKind[] {arg1, arg2, arg3}).run(comp, fm);
mcimadamore@1060 218 continue;
mcimadamore@1060 219 }
mcimadamore@1060 220 }
mcimadamore@1060 221 }
mcimadamore@1060 222 }
mcimadamore@1060 223 }
mcimadamore@1060 224 }
mcimadamore@1060 225 }
mcimadamore@1060 226 }
mcimadamore@1060 227 }
mcimadamore@1060 228 }
mcimadamore@1060 229 }
mcimadamore@1060 230 }
mcimadamore@1060 231 }
mcimadamore@1060 232 }
mcimadamore@1060 233 System.out.println("Total check executed: " + checkCount);
mcimadamore@1060 234 }
mcimadamore@1060 235
mcimadamore@1060 236 InnerClassDeclArity innerClassDeclArity;
mcimadamore@1060 237 TypeQualifierArity declType;
mcimadamore@1060 238 TypeQualifierArity siteType;
mcimadamore@1060 239 ArgumentListArity argList;
mcimadamore@1060 240 TypeArgumentKind[] declTypeArgumentKinds;
mcimadamore@1060 241 TypeArgumentKind[] siteTypeArgumentKinds;
mcimadamore@1060 242 ArgumentKind[] argumentKinds;
mcimadamore@1060 243 JavaSource source;
mcimadamore@1060 244 DiagnosticChecker diagChecker;
mcimadamore@1060 245
mcimadamore@1060 246 DiamondAndInnerClassTest(InnerClassDeclArity innerClassDeclArity,
mcimadamore@1060 247 TypeQualifierArity declType, TypeQualifierArity siteType, ArgumentListArity argList,
mcimadamore@1060 248 TypeArgumentKind[] declTypeArgumentKinds, TypeArgumentKind[] siteTypeArgumentKinds,
mcimadamore@1060 249 ArgumentKind[] argumentKinds) {
mcimadamore@1060 250 this.innerClassDeclArity = innerClassDeclArity;
mcimadamore@1060 251 this.declType = declType;
mcimadamore@1060 252 this.siteType = siteType;
mcimadamore@1060 253 this.argList = argList;
mcimadamore@1060 254 this.declTypeArgumentKinds = declTypeArgumentKinds;
mcimadamore@1060 255 this.siteTypeArgumentKinds = siteTypeArgumentKinds;
mcimadamore@1060 256 this.argumentKinds = argumentKinds;
mcimadamore@1060 257 this.source = new JavaSource();
mcimadamore@1060 258 this.diagChecker = new DiagnosticChecker();
mcimadamore@1060 259 }
mcimadamore@1060 260
mcimadamore@1060 261 class JavaSource extends SimpleJavaFileObject {
mcimadamore@1060 262
mcimadamore@1060 263 String bodyTemplate = "#D res = new #S#AL;";
mcimadamore@1060 264
mcimadamore@1060 265 String source;
mcimadamore@1060 266
mcimadamore@1060 267 public JavaSource() {
mcimadamore@1060 268 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
mcimadamore@1060 269 source = innerClassDeclArity.classDeclStr.replace("#B", bodyTemplate)
mcimadamore@1060 270 .replace("#D", declType.getType(declTypeArgumentKinds))
mcimadamore@1060 271 .replace("#S", siteType.getType(siteTypeArgumentKinds))
mcimadamore@1060 272 .replace("#AL", argList.getArgs(argumentKinds));
mcimadamore@1060 273 }
mcimadamore@1060 274
mcimadamore@1060 275 @Override
mcimadamore@1060 276 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
mcimadamore@1060 277 return source;
mcimadamore@1060 278 }
mcimadamore@1060 279 }
mcimadamore@1060 280
mcimadamore@1060 281 void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
mcimadamore@1060 282 JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
mcimadamore@1060 283 null, null, Arrays.asList(source));
mcimadamore@1060 284 try {
mcimadamore@1060 285 ct.analyze();
mcimadamore@1060 286 } catch (Throwable ex) {
jjg@1169 287 throw new AssertionError("Error thrown when compiling the following code:\n" + source.getCharContent(true));
mcimadamore@1060 288 }
mcimadamore@1060 289 check();
mcimadamore@1060 290 }
mcimadamore@1060 291
mcimadamore@1060 292 void check() {
mcimadamore@1060 293 checkCount++;
mcimadamore@1060 294
mcimadamore@1060 295 boolean errorExpected = false;
mcimadamore@1060 296
mcimadamore@1060 297 TypeArgumentKind[] expectedArgKinds = new TypeArgumentKind[innerClassDeclArity.n];
mcimadamore@1060 298
mcimadamore@1060 299 for (int i = 0 ; i < innerClassDeclArity.n ; i++) {
mcimadamore@1060 300 if (!declTypeArgumentKinds[i].compatible(siteTypeArgumentKinds[i])) {
mcimadamore@1060 301 errorExpected = true;
mcimadamore@1060 302 break;
mcimadamore@1060 303 }
mcimadamore@1060 304 expectedArgKinds[i] = siteTypeArgumentKinds[i] == TypeArgumentKind.DIAMOND ?
mcimadamore@1060 305 declTypeArgumentKinds[i] : siteTypeArgumentKinds[i];
mcimadamore@1060 306 }
mcimadamore@1060 307
mcimadamore@1060 308 if (!errorExpected) {
mcimadamore@1060 309 for (int i = 0 ; i < innerClassDeclArity.n ; i++) {
mcimadamore@1060 310 //System.out.println("check " + expectedArgKinds[i] + " against " + argumentKinds[i]);
mcimadamore@1060 311 if (!expectedArgKinds[i].compatible(argumentKinds[i])) {
mcimadamore@1060 312 errorExpected = true;
mcimadamore@1060 313 break;
mcimadamore@1060 314 }
mcimadamore@1060 315 }
mcimadamore@1060 316 }
mcimadamore@1060 317
mcimadamore@1060 318 if (errorExpected != diagChecker.errorFound) {
mcimadamore@1060 319 throw new Error("invalid diagnostics for source:\n" +
mcimadamore@1060 320 source.getCharContent(true) +
mcimadamore@1060 321 "\nFound error: " + diagChecker.errorFound +
mcimadamore@1060 322 "\nExpected error: " + errorExpected);
mcimadamore@1060 323 }
mcimadamore@1060 324 }
mcimadamore@1060 325
mcimadamore@1060 326 static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
mcimadamore@1060 327
mcimadamore@1060 328 boolean errorFound;
mcimadamore@1060 329
mcimadamore@1060 330 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
mcimadamore@1060 331 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
mcimadamore@1060 332 errorFound = true;
mcimadamore@1060 333 }
mcimadamore@1060 334 }
mcimadamore@1060 335 }
mcimadamore@1060 336 }

mercurial