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