test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java

Thu, 21 Feb 2013 14:43:51 -0800

author
rfield
date
Thu, 21 Feb 2013 14:43:51 -0800
changeset 1601
cd7340a84bb8
parent 1520
5c956be64b9e
child 2020
bb7271e64ef6
permissions
-rw-r--r--

8008405: Now that metafactory is in place, add javac lambda serialization tests
Summary: Tests part of original langtools serialization review.
Reviewed-by: mcimadamore

mcimadamore@1393 1 /*
vromero@1482 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
mcimadamore@1393 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
mcimadamore@1393 4 *
mcimadamore@1393 5 * This code is free software; you can redistribute it and/or modify it
mcimadamore@1393 6 * under the terms of the GNU General Public License version 2 only, as
mcimadamore@1393 7 * published by the Free Software Foundation.
mcimadamore@1393 8 *
mcimadamore@1393 9 * This code is distributed in the hope that it will be useful, but WITHOUT
mcimadamore@1393 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
mcimadamore@1393 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
mcimadamore@1393 12 * version 2 for more details (a copy is included in the LICENSE file that
mcimadamore@1393 13 * accompanied this code).
mcimadamore@1393 14 *
mcimadamore@1393 15 * You should have received a copy of the GNU General Public License version
mcimadamore@1393 16 * 2 along with this work; if not, write to the Free Software Foundation,
mcimadamore@1393 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
mcimadamore@1393 18 *
mcimadamore@1393 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
mcimadamore@1393 20 * or visit www.oracle.com if you need additional information or have any
mcimadamore@1393 21 * questions.
mcimadamore@1393 22 */
mcimadamore@1393 23
mcimadamore@1393 24 /*
mcimadamore@1393 25 * @test
vromero@1520 26 * @bug 8006694
mcimadamore@1393 27 * @summary Automatic test for checking correctness of default super/this resolution
vromero@1520 28 * temporarily workaround combo tests are causing time out in several platforms
vromero@1482 29 * @library ../../lib
vromero@1482 30 * @build JavacTestingAbstractThreadedTest
vromero@1520 31 * @run main/othervm TestDefaultSuperCall
mcimadamore@1393 32 */
mcimadamore@1393 33
vromero@1520 34 // use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
vromero@1520 35 // see JDK-8006746
vromero@1520 36
mcimadamore@1393 37 import java.net.URI;
mcimadamore@1393 38 import java.util.Arrays;
mcimadamore@1393 39 import java.util.ArrayList;
mcimadamore@1393 40 import java.util.List;
mcimadamore@1393 41 import javax.tools.Diagnostic;
mcimadamore@1393 42 import javax.tools.JavaFileObject;
mcimadamore@1393 43 import javax.tools.SimpleJavaFileObject;
mcimadamore@1393 44
vromero@1482 45 import com.sun.source.util.JavacTask;
mcimadamore@1393 46
vromero@1482 47 public class TestDefaultSuperCall
vromero@1482 48 extends JavacTestingAbstractThreadedTest
vromero@1482 49 implements Runnable {
mcimadamore@1393 50
mcimadamore@1393 51 enum InterfaceKind {
mcimadamore@1393 52 DEFAULT("interface A extends B { default void m() { } }"),
mcimadamore@1393 53 ABSTRACT("interface A extends B { void m(); }"),
mcimadamore@1393 54 NONE("interface A extends B { }");
mcimadamore@1393 55
mcimadamore@1393 56 String interfaceStr;
mcimadamore@1393 57
mcimadamore@1393 58 InterfaceKind(String interfaceStr) {
mcimadamore@1393 59 this.interfaceStr = interfaceStr;
mcimadamore@1393 60 }
mcimadamore@1393 61
mcimadamore@1393 62 boolean methodDefined() {
mcimadamore@1393 63 return this == DEFAULT;
mcimadamore@1393 64 }
mcimadamore@1393 65 }
mcimadamore@1393 66
mcimadamore@1393 67 enum PruneKind {
mcimadamore@1393 68 NO_PRUNE("interface C { }"),
mcimadamore@1393 69 PRUNE("interface C extends A { }");
mcimadamore@1393 70
mcimadamore@1393 71 boolean methodDefined(InterfaceKind ik) {
mcimadamore@1393 72 return this == PRUNE &&
mcimadamore@1393 73 ik.methodDefined();
mcimadamore@1393 74 }
mcimadamore@1393 75
mcimadamore@1393 76 String interfaceStr;
mcimadamore@1393 77
mcimadamore@1393 78 PruneKind(String interfaceStr) {
mcimadamore@1393 79 this.interfaceStr = interfaceStr;
mcimadamore@1393 80 }
mcimadamore@1393 81 }
mcimadamore@1393 82
mcimadamore@1393 83 enum QualifierKind {
mcimadamore@1393 84 DIRECT_1("C"),
mcimadamore@1393 85 DIRECT_2("A"),
mcimadamore@1393 86 INDIRECT("B"),
mcimadamore@1393 87 UNRELATED("E"),
mcimadamore@1393 88 ENCLOSING_1(null),
mcimadamore@1393 89 ENCLOSING_2(null);
mcimadamore@1393 90
mcimadamore@1393 91 String qualifierStr;
mcimadamore@1393 92
mcimadamore@1393 93 QualifierKind(String qualifierStr) {
mcimadamore@1393 94 this.qualifierStr = qualifierStr;
mcimadamore@1393 95 }
mcimadamore@1393 96
mcimadamore@1393 97 String getQualifier(Shape sh) {
mcimadamore@1393 98 switch (this) {
mcimadamore@1393 99 case ENCLOSING_1: return sh.enclosingAt(0);
mcimadamore@1393 100 case ENCLOSING_2: return sh.enclosingAt(1);
mcimadamore@1393 101 default:
mcimadamore@1393 102 return qualifierStr;
mcimadamore@1393 103 }
mcimadamore@1393 104 }
mcimadamore@1393 105
mcimadamore@1393 106 boolean isEnclosing() {
mcimadamore@1393 107 return this == ENCLOSING_1 ||
mcimadamore@1393 108 this == ENCLOSING_2;
mcimadamore@1393 109 }
mcimadamore@1393 110
mcimadamore@1393 111 boolean allowSuperCall(InterfaceKind ik, PruneKind pk) {
mcimadamore@1393 112 switch (this) {
mcimadamore@1393 113 case DIRECT_1:
mcimadamore@1393 114 return pk.methodDefined(ik);
mcimadamore@1393 115 case DIRECT_2:
mcimadamore@1393 116 return ik.methodDefined() && pk == PruneKind.NO_PRUNE;
mcimadamore@1393 117 default:
mcimadamore@1393 118 return false;
mcimadamore@1393 119 }
mcimadamore@1393 120 }
mcimadamore@1393 121 }
mcimadamore@1393 122
mcimadamore@1393 123 enum ExprKind {
mcimadamore@1393 124 THIS("this"),
mcimadamore@1393 125 SUPER("super");
mcimadamore@1393 126
mcimadamore@1393 127 String exprStr;
mcimadamore@1393 128
mcimadamore@1393 129 ExprKind(String exprStr) {
mcimadamore@1393 130 this.exprStr = exprStr;
mcimadamore@1393 131 }
mcimadamore@1393 132 }
mcimadamore@1393 133
mcimadamore@1393 134 enum ElementKind {
mcimadamore@1393 135 INTERFACE("interface #N { #B }", true),
mcimadamore@1393 136 INTERFACE_EXTENDS("interface #N extends A, C { #B }", true),
mcimadamore@1393 137 CLASS("class #N { #B }", false),
mcimadamore@1393 138 CLASS_EXTENDS("abstract class #N implements A, C { #B }", false),
mcimadamore@1393 139 STATIC_CLASS("static class #N { #B }", true),
mcimadamore@1393 140 STATIC_CLASS_EXTENDS("abstract static class #N implements A, C { #B }", true),
mcimadamore@1393 141 ANON_CLASS("new Object() { #B };", false),
mcimadamore@1393 142 METHOD("void test() { #B }", false),
mcimadamore@1393 143 STATIC_METHOD("static void test() { #B }", true),
mcimadamore@1393 144 DEFAULT_METHOD("default void test() { #B }", false);
mcimadamore@1393 145
mcimadamore@1393 146 String templateDecl;
mcimadamore@1393 147 boolean isStatic;
mcimadamore@1393 148
mcimadamore@1393 149 ElementKind(String templateDecl, boolean isStatic) {
mcimadamore@1393 150 this.templateDecl = templateDecl;
mcimadamore@1393 151 this.isStatic = isStatic;
mcimadamore@1393 152 }
mcimadamore@1393 153
mcimadamore@1393 154 boolean isClassDecl() {
mcimadamore@1393 155 switch(this) {
mcimadamore@1393 156 case METHOD:
mcimadamore@1393 157 case STATIC_METHOD:
mcimadamore@1393 158 case DEFAULT_METHOD:
mcimadamore@1393 159 return false;
mcimadamore@1393 160 default:
mcimadamore@1393 161 return true;
mcimadamore@1393 162 }
mcimadamore@1393 163 }
mcimadamore@1393 164
mcimadamore@1393 165 boolean isAllowedEnclosing(ElementKind ek, boolean isTop) {
mcimadamore@1393 166 switch (this) {
mcimadamore@1393 167 case CLASS:
mcimadamore@1393 168 case CLASS_EXTENDS:
mcimadamore@1393 169 //class is implicitly static inside interface, so skip this combo
mcimadamore@1393 170 return ek.isClassDecl() &&
mcimadamore@1393 171 ek != INTERFACE && ek != INTERFACE_EXTENDS;
mcimadamore@1393 172 case ANON_CLASS:
mcimadamore@1393 173 return !ek.isClassDecl();
mcimadamore@1393 174 case METHOD:
mcimadamore@1393 175 return ek == CLASS || ek == CLASS_EXTENDS ||
mcimadamore@1393 176 ek == STATIC_CLASS || ek == STATIC_CLASS_EXTENDS ||
mcimadamore@1393 177 ek == ANON_CLASS;
mcimadamore@1393 178 case INTERFACE:
mcimadamore@1393 179 case INTERFACE_EXTENDS:
mcimadamore@1393 180 case STATIC_CLASS:
mcimadamore@1393 181 case STATIC_CLASS_EXTENDS:
mcimadamore@1393 182 case STATIC_METHOD:
mcimadamore@1393 183 return (isTop && (ek == CLASS || ek == CLASS_EXTENDS)) ||
mcimadamore@1393 184 ek == STATIC_CLASS || ek == STATIC_CLASS_EXTENDS;
mcimadamore@1393 185 case DEFAULT_METHOD:
mcimadamore@1393 186 return ek == INTERFACE || ek == INTERFACE_EXTENDS;
mcimadamore@1393 187 default:
mcimadamore@1393 188 throw new AssertionError("Bad enclosing element kind" + this);
mcimadamore@1393 189 }
mcimadamore@1393 190 }
mcimadamore@1393 191
mcimadamore@1393 192 boolean isAllowedTop() {
mcimadamore@1393 193 switch (this) {
mcimadamore@1393 194 case CLASS:
mcimadamore@1393 195 case CLASS_EXTENDS:
mcimadamore@1393 196 case INTERFACE:
mcimadamore@1393 197 case INTERFACE_EXTENDS:
mcimadamore@1393 198 return true;
mcimadamore@1393 199 default:
mcimadamore@1393 200 return false;
mcimadamore@1393 201 }
mcimadamore@1393 202 }
mcimadamore@1393 203
mcimadamore@1393 204 boolean hasSuper() {
mcimadamore@1393 205 return this == INTERFACE_EXTENDS ||
mcimadamore@1393 206 this == STATIC_CLASS_EXTENDS ||
mcimadamore@1393 207 this == CLASS_EXTENDS;
mcimadamore@1393 208 }
mcimadamore@1393 209 }
mcimadamore@1393 210
mcimadamore@1393 211 static class Shape {
mcimadamore@1393 212
mcimadamore@1393 213 String shapeStr;
mcimadamore@1393 214 List<ElementKind> enclosingElements;
mcimadamore@1393 215 List<String> enclosingNames;
mcimadamore@1393 216 List<String> elementsWithMethod;
mcimadamore@1393 217
mcimadamore@1393 218 Shape(ElementKind... elements) {
mcimadamore@1393 219 enclosingElements = new ArrayList<>();
mcimadamore@1393 220 enclosingNames = new ArrayList<>();
mcimadamore@1393 221 elementsWithMethod = new ArrayList<>();
mcimadamore@1393 222 int count = 0;
mcimadamore@1393 223 String prevName = null;
mcimadamore@1393 224 for (ElementKind ek : elements) {
mcimadamore@1393 225 String name = "name"+count++;
mcimadamore@1393 226 if (ek.isStatic) {
mcimadamore@1393 227 enclosingElements = new ArrayList<>();
mcimadamore@1393 228 enclosingNames = new ArrayList<>();
mcimadamore@1393 229 }
mcimadamore@1393 230 if (ek.isClassDecl()) {
mcimadamore@1393 231 enclosingElements.add(ek);
mcimadamore@1393 232 enclosingNames.add(name);
mcimadamore@1393 233 } else {
mcimadamore@1393 234 elementsWithMethod.add(prevName);
mcimadamore@1393 235 }
mcimadamore@1393 236 String element = ek.templateDecl.replaceAll("#N", name);
vromero@1482 237 shapeStr = shapeStr ==
vromero@1482 238 null ? element : shapeStr.replaceAll("#B", element);
mcimadamore@1393 239 prevName = name;
mcimadamore@1393 240 }
mcimadamore@1393 241 }
mcimadamore@1393 242
mcimadamore@1393 243 String getShape(QualifierKind qk, ExprKind ek) {
mcimadamore@1393 244 String methName = ek == ExprKind.THIS ? "test" : "m";
vromero@1482 245 String call = qk.getQualifier(this) + "." +
vromero@1482 246 ek.exprStr + "." + methName + "();";
mcimadamore@1393 247 return shapeStr.replaceAll("#B", call);
mcimadamore@1393 248 }
mcimadamore@1393 249
mcimadamore@1393 250 String enclosingAt(int index) {
vromero@1482 251 return index < enclosingNames.size() ?
vromero@1482 252 enclosingNames.get(index) : "BAD";
mcimadamore@1393 253 }
mcimadamore@1393 254 }
mcimadamore@1393 255
mcimadamore@1393 256 public static void main(String... args) throws Exception {
mcimadamore@1393 257 for (InterfaceKind ik : InterfaceKind.values()) {
mcimadamore@1393 258 for (PruneKind pk : PruneKind.values()) {
mcimadamore@1393 259 for (ElementKind ek1 : ElementKind.values()) {
mcimadamore@1393 260 if (!ek1.isAllowedTop()) continue;
mcimadamore@1393 261 for (ElementKind ek2 : ElementKind.values()) {
mcimadamore@1393 262 if (!ek2.isAllowedEnclosing(ek1, true)) continue;
mcimadamore@1393 263 for (ElementKind ek3 : ElementKind.values()) {
mcimadamore@1393 264 if (!ek3.isAllowedEnclosing(ek2, false)) continue;
mcimadamore@1393 265 for (ElementKind ek4 : ElementKind.values()) {
mcimadamore@1393 266 if (!ek4.isAllowedEnclosing(ek3, false)) continue;
mcimadamore@1393 267 for (ElementKind ek5 : ElementKind.values()) {
vromero@1482 268 if (!ek5.isAllowedEnclosing(ek4, false) ||
vromero@1482 269 ek5.isClassDecl()) continue;
mcimadamore@1393 270 for (QualifierKind qk : QualifierKind.values()) {
mcimadamore@1393 271 for (ExprKind ek : ExprKind.values()) {
vromero@1482 272 pool.execute(
vromero@1482 273 new TestDefaultSuperCall(ik, pk,
vromero@1482 274 new Shape(ek1, ek2, ek3,
vromero@1482 275 ek4, ek5), qk, ek));
mcimadamore@1393 276 }
mcimadamore@1393 277 }
mcimadamore@1393 278 }
mcimadamore@1393 279 }
mcimadamore@1393 280 }
mcimadamore@1393 281 }
mcimadamore@1393 282 }
mcimadamore@1393 283 }
mcimadamore@1393 284 }
vromero@1482 285
vromero@1482 286 checkAfterExec();
mcimadamore@1393 287 }
mcimadamore@1393 288
mcimadamore@1393 289 InterfaceKind ik;
mcimadamore@1393 290 PruneKind pk;
mcimadamore@1393 291 Shape sh;
mcimadamore@1393 292 QualifierKind qk;
mcimadamore@1393 293 ExprKind ek;
mcimadamore@1393 294 JavaSource source;
mcimadamore@1393 295 DiagnosticChecker diagChecker;
mcimadamore@1393 296
vromero@1482 297 TestDefaultSuperCall(InterfaceKind ik, PruneKind pk, Shape sh,
vromero@1482 298 QualifierKind qk, ExprKind ek) {
mcimadamore@1393 299 this.ik = ik;
mcimadamore@1393 300 this.pk = pk;
mcimadamore@1393 301 this.sh = sh;
mcimadamore@1393 302 this.qk = qk;
mcimadamore@1393 303 this.ek = ek;
mcimadamore@1393 304 this.source = new JavaSource();
mcimadamore@1393 305 this.diagChecker = new DiagnosticChecker();
mcimadamore@1393 306 }
mcimadamore@1393 307
mcimadamore@1393 308 class JavaSource extends SimpleJavaFileObject {
mcimadamore@1393 309
mcimadamore@1393 310 String template = "interface E {}\n" +
mcimadamore@1393 311 "interface B { }\n" +
mcimadamore@1393 312 "#I\n" +
mcimadamore@1393 313 "#P\n" +
mcimadamore@1393 314 "#C";
mcimadamore@1393 315
mcimadamore@1393 316 String source;
mcimadamore@1393 317
mcimadamore@1393 318 public JavaSource() {
mcimadamore@1393 319 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
mcimadamore@1393 320 source = template.replaceAll("#I", ik.interfaceStr)
mcimadamore@1393 321 .replaceAll("#P", pk.interfaceStr)
mcimadamore@1393 322 .replaceAll("#C", sh.getShape(qk, ek));
mcimadamore@1393 323 }
mcimadamore@1393 324
mcimadamore@1393 325 @Override
mcimadamore@1393 326 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
mcimadamore@1393 327 return source;
mcimadamore@1393 328 }
mcimadamore@1393 329 }
mcimadamore@1393 330
vromero@1482 331 public void run() {
vromero@1482 332 JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
mcimadamore@1415 333 null, null, Arrays.asList(source));
mcimadamore@1393 334 try {
mcimadamore@1393 335 ct.analyze();
mcimadamore@1393 336 } catch (Throwable ex) {
vromero@1482 337 processException(ex);
vromero@1482 338 return;
mcimadamore@1393 339 }
mcimadamore@1393 340 check();
mcimadamore@1393 341 }
mcimadamore@1393 342
mcimadamore@1393 343 void check() {
mcimadamore@1393 344 boolean errorExpected = false;
mcimadamore@1393 345
mcimadamore@1393 346 boolean badEnclosing = false;
mcimadamore@1393 347 boolean badThis = false;
mcimadamore@1393 348 boolean badSuper = false;
mcimadamore@1393 349
mcimadamore@1393 350 if (qk == QualifierKind.ENCLOSING_1 &&
mcimadamore@1393 351 sh.enclosingNames.size() < 1) {
mcimadamore@1393 352 errorExpected |= true;
mcimadamore@1393 353 badEnclosing = true;
mcimadamore@1393 354 }
mcimadamore@1393 355
mcimadamore@1393 356 if (qk == QualifierKind.ENCLOSING_2 &&
mcimadamore@1393 357 sh.enclosingNames.size() < 2) {
mcimadamore@1393 358 errorExpected |= true;
mcimadamore@1393 359 badEnclosing = true;
mcimadamore@1393 360 }
mcimadamore@1393 361
mcimadamore@1393 362 if (ek == ExprKind.THIS) {
mcimadamore@1393 363 boolean found = false;
mcimadamore@1393 364 for (int i = 0; i < sh.enclosingElements.size(); i++) {
mcimadamore@1393 365 if (sh.enclosingElements.get(i) == ElementKind.ANON_CLASS) continue;
mcimadamore@1393 366 if (sh.enclosingNames.get(i).equals(qk.getQualifier(sh))) {
mcimadamore@1393 367 found = sh.elementsWithMethod.contains(sh.enclosingNames.get(i));
mcimadamore@1393 368 break;
mcimadamore@1393 369 }
mcimadamore@1393 370 }
mcimadamore@1393 371 errorExpected |= !found;
mcimadamore@1393 372 if (!found) {
mcimadamore@1393 373 badThis = true;
mcimadamore@1393 374 }
mcimadamore@1393 375 }
mcimadamore@1393 376
mcimadamore@1393 377 if (ek == ExprKind.SUPER) {
mcimadamore@1393 378
mcimadamore@1393 379 int lastIdx = sh.enclosingElements.size() - 1;
mcimadamore@1393 380 boolean found = lastIdx == -1 ? false :
vromero@1482 381 sh.enclosingElements.get(lastIdx).hasSuper() &&
vromero@1482 382 qk.allowSuperCall(ik, pk);
mcimadamore@1393 383
mcimadamore@1393 384 errorExpected |= !found;
mcimadamore@1393 385 if (!found) {
mcimadamore@1393 386 badSuper = true;
mcimadamore@1393 387 }
mcimadamore@1393 388 }
mcimadamore@1393 389
vromero@1482 390 checkCount.incrementAndGet();
mcimadamore@1393 391 if (diagChecker.errorFound != errorExpected) {
vromero@1482 392 throw new AssertionError("Problem when compiling source:\n" +
vromero@1482 393 source.getCharContent(true) +
mcimadamore@1393 394 "\nenclosingElems: " + sh.enclosingElements +
mcimadamore@1393 395 "\nenclosingNames: " + sh.enclosingNames +
mcimadamore@1393 396 "\nelementsWithMethod: " + sh.elementsWithMethod +
mcimadamore@1393 397 "\nbad encl: " + badEnclosing +
mcimadamore@1393 398 "\nbad this: " + badThis +
mcimadamore@1393 399 "\nbad super: " + badSuper +
mcimadamore@1393 400 "\nqual kind: " + qk +
mcimadamore@1393 401 "\nfound error: " + diagChecker.errorFound);
mcimadamore@1393 402 }
mcimadamore@1393 403 }
mcimadamore@1393 404
vromero@1482 405 static class DiagnosticChecker
vromero@1482 406 implements javax.tools.DiagnosticListener<JavaFileObject> {
mcimadamore@1393 407
mcimadamore@1393 408 boolean errorFound;
mcimadamore@1393 409
mcimadamore@1393 410 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
mcimadamore@1393 411 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
mcimadamore@1393 412 errorFound = true;
mcimadamore@1393 413 }
mcimadamore@1393 414 }
mcimadamore@1393 415 }
vromero@1482 416
mcimadamore@1393 417 }

mercurial