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 7046778 8006694 8129962 27 * @summary Project Coin: problem with diamond and member inner classes 28 * temporarily workaround combo tests are causing time out in several platforms 29 * @library /tools/javac/lib 30 * @modules jdk.compiler/com.sun.tools.javac.api 31 * jdk.compiler/com.sun.tools.javac.file 32 * jdk.compiler/com.sun.tools.javac.util 33 * @build combo.ComboTestHelper 34 * @compile -Xlint:all DiamondAndInnerClassTest.java 35 * @run main DiamondAndInnerClassTest 36 */ 37 38 import java.io.IOException; 39 import java.util.Arrays; 40 41 import combo.ComboTestHelper; 42 import combo.ComboInstance; 43 import combo.ComboParameter; 44 import combo.ComboTask.Result; 45 46 public class DiamondAndInnerClassTest extends ComboInstance<DiamondAndInnerClassTest> { 47 48 enum TypeArgumentKind implements ComboParameter { 49 NONE(""), 50 STRING("<String>"), 51 INTEGER("<Integer>"), 52 DIAMOND("<>"); 53 54 String typeargStr; 55 56 TypeArgumentKind(String typeargStr) { 57 this.typeargStr = typeargStr; 58 } 59 60 boolean compatible(TypeArgumentKind that) { 61 switch (this) { 62 case NONE: return true; 63 case STRING: return that != INTEGER; 64 case INTEGER: return that != STRING; 65 default: throw new AssertionError("Unexpected decl kind: " + this); 66 } 67 } 68 69 boolean compatible(ArgumentKind that) { 70 switch (this) { 71 case NONE: return true; 72 case STRING: return that == ArgumentKind.STRING; 73 case INTEGER: return that == ArgumentKind.INTEGER; 74 default: throw new AssertionError("Unexpected decl kind: " + this); 75 } 76 } 77 78 @Override 79 public String expand(String optParameter) { 80 return typeargStr; 81 } 82 } 83 84 enum ArgumentKind implements ComboParameter { 85 OBJECT("(Object)null"), 86 STRING("(String)null"), 87 INTEGER("(Integer)null"); 88 89 String argStr; 90 91 ArgumentKind(String argStr) { 92 this.argStr = argStr; 93 } 94 95 @Override 96 public String expand(String optParameter) { 97 return argStr; 98 } 99 } 100 101 enum TypeQualifierArity implements ComboParameter { 102 ONE(1, "A1#{TA#IDX[0]}"), 103 TWO(2, "A1#{TA#IDX[0]}.A2#{TA#IDX[1]}"), 104 THREE(3, "A1#{TA#IDX[0]}.A2#{TA#IDX[1]}.A3#{TA#IDX[2]}"); 105 106 int n; 107 String qualifierStr; 108 109 TypeQualifierArity(int n, String qualifierStr) { 110 this.n = n; 111 this.qualifierStr = qualifierStr; 112 } 113 114 @Override 115 public String expand(String optParameter) { 116 return qualifierStr.replaceAll("#IDX", optParameter); 117 } 118 } 119 120 enum InnerClassDeclArity implements ComboParameter { 121 ONE(1, "class A1<X> { A1(X x1) { } #{BODY} }"), 122 TWO(2, "class A1<X1> { class A2<X2> { A2(X1 x1, X2 x2) { } #{BODY} } }"), 123 THREE(3, "class A1<X1> { class A2<X2> { class A3<X3> { A3(X1 x1, X2 x2, X3 x3) { } #{BODY} } } }"); 124 125 int n; 126 String classDeclStr; 127 128 InnerClassDeclArity(int n, String classDeclStr) { 129 this.n = n; 130 this.classDeclStr = classDeclStr; 131 } 132 133 @Override 134 public String expand(String optParameter) { 135 return classDeclStr; 136 } 137 } 138 139 enum ArgumentListArity implements ComboParameter { 140 ONE(1, "(#{A[0]})"), 141 TWO(2, "(#{A[0]},#{A[1]})"), 142 THREE(3, "(#{A[0]},#{A[1]},#{A[2]})"); 143 144 int n; 145 String argListStr; 146 147 ArgumentListArity(int n, String argListStr) { 148 this.n = n; 149 this.argListStr = argListStr; 150 } 151 152 @Override 153 public String expand(String optParameter) { 154 return argListStr.replaceAll("#IDX", optParameter); 155 } 156 } 157 158 public static void main(String... args) throws Exception { 159 new ComboTestHelper<DiamondAndInnerClassTest>() 160 .withFilter(DiamondAndInnerClassTest::rareTypesFilter) 161 .withFilter(DiamondAndInnerClassTest::noDiamondOnDecl) 162 .withFilter(DiamondAndInnerClassTest::noDiamondOnIntermediateTypes) 163 .withFilter(DiamondAndInnerClassTest::arityMismatch) 164 .withFilter(DiamondAndInnerClassTest::redundantFilter) 165 .withDimension("BODY", new ComboParameter.Constant<>("#{D.1} res = new #{S.2}#{AL};")) 166 .withDimension("DECL", (x, arity) -> x.innerClassDeclArity = arity, InnerClassDeclArity.values()) 167 .withDimension("D", (x, arity) -> x.declArity = arity, TypeQualifierArity.values()) 168 .withDimension("S", (x, arity) -> x.siteArity = arity, TypeQualifierArity.values()) 169 .withDimension("AL", (x, alist) -> x.argumentListArity = alist, ArgumentListArity.values()) 170 .withArrayDimension("TA1", (x, targs, idx) -> x.declTypeArgumentKinds[idx] = targs, 3, TypeArgumentKind.values()) 171 .withArrayDimension("TA2", (x, targs, idx) -> x.siteTypeArgumentKinds[idx] = targs, 3, TypeArgumentKind.values()) 172 .withArrayDimension("A", (x, argsk, idx) -> x.argumentKinds[idx] = argsk, 3, ArgumentKind.values()) 173 .run(DiamondAndInnerClassTest::new); 174 } 175 176 InnerClassDeclArity innerClassDeclArity; 177 TypeQualifierArity declArity; 178 TypeQualifierArity siteArity; 179 TypeArgumentKind[] declTypeArgumentKinds = new TypeArgumentKind[3]; 180 TypeArgumentKind[] siteTypeArgumentKinds = new TypeArgumentKind[3]; 181 ArgumentKind[] argumentKinds = new ArgumentKind[3]; 182 ArgumentListArity argumentListArity; 183 184 boolean rareTypesFilter() { 185 for (TypeArgumentKind[] types : Arrays.asList(declTypeArgumentKinds, siteTypeArgumentKinds)) { 186 boolean isRaw = types[0] == TypeArgumentKind.NONE; 187 for (int i = 1; i < innerClassDeclArity.n; i++) { 188 if (isRaw != (types[i] == TypeArgumentKind.NONE)) { 189 return false; 190 } 191 } 192 } 193 return true; 194 } 195 196 boolean noDiamondOnDecl() { 197 for (int i = 0; i < innerClassDeclArity.n; i++) { 198 if (declTypeArgumentKinds[i] == TypeArgumentKind.DIAMOND) { 199 return false; 200 } 201 } 202 return true; 203 } 204 205 boolean noDiamondOnIntermediateTypes() { 206 for (int i = 0; i < (innerClassDeclArity.n - 1); i++) { 207 if (siteTypeArgumentKinds[i] == TypeArgumentKind.DIAMOND) { 208 return false; 209 } 210 } 211 return true; 212 } 213 214 boolean redundantFilter() { 215 for (TypeArgumentKind[] types : Arrays.asList(declTypeArgumentKinds, siteTypeArgumentKinds)) { 216 for (int i = innerClassDeclArity.n; i < types.length; i++) { 217 if (types[i].ordinal() != 0) { 218 return false; 219 } 220 } 221 } 222 for (int i = innerClassDeclArity.n; i < argumentKinds.length; i++) { 223 if (argumentKinds[i].ordinal() != 0) { 224 return false; 225 } 226 } 227 return true; 228 } 229 230 boolean arityMismatch() { 231 return argumentListArity.n == innerClassDeclArity.n && 232 siteArity.n == innerClassDeclArity.n && 233 declArity.n == innerClassDeclArity.n; 234 } 235 236 @Override 237 public void doWork() throws IOException { 238 newCompilationTask() 239 .withSourceFromTemplate("#{DECL}") 240 .analyze(this::check); 241 } 242 243 void check(Result<?> res) { 244 boolean errorExpected = false; 245 246 TypeArgumentKind[] expectedArgKinds = 247 new TypeArgumentKind[innerClassDeclArity.n]; 248 249 for (int i = 0 ; i < innerClassDeclArity.n ; i++) { 250 if (!declTypeArgumentKinds[i].compatible(siteTypeArgumentKinds[i])) { 251 errorExpected = true; 252 break; 253 } 254 expectedArgKinds[i] = siteTypeArgumentKinds[i] == 255 TypeArgumentKind.DIAMOND ? 256 declTypeArgumentKinds[i] : siteTypeArgumentKinds[i]; 257 } 258 259 if (!errorExpected) { 260 for (int i = 0 ; i < innerClassDeclArity.n ; i++) { 261 if (!expectedArgKinds[i].compatible(argumentKinds[i])) { 262 errorExpected = true; 263 break; 264 } 265 } 266 } 267 268 if (errorExpected != res.hasErrors()) { 269 fail("invalid diagnostics for source:\n" + 270 res.compilationInfo() + 271 "\nFound error: " + res.hasErrors() + 272 "\nExpected error: " + errorExpected); 273 } 274 } 275 }