test/tools/javac/cast/intersection/IntersectionTypeCastTest.java

Wed, 23 Jan 2013 20:57:40 +0000

author
vromero
date
Wed, 23 Jan 2013 20:57:40 +0000
changeset 1520
5c956be64b9e
parent 1511
c7c41a044e7c
child 2047
5f915a0c9615
permissions
-rw-r--r--

8006694: temporarily workaround combo tests are causing time out in several platforms
Reviewed-by: jjg
Contributed-by: maurizio.cimadamore@oracle.com

mcimadamore@1436 1 /*
vromero@1482 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
mcimadamore@1436 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
mcimadamore@1436 4 *
mcimadamore@1436 5 * This code is free software; you can redistribute it and/or modify it
mcimadamore@1436 6 * under the terms of the GNU General Public License version 2 only, as
mcimadamore@1436 7 * published by the Free Software Foundation.
mcimadamore@1436 8 *
mcimadamore@1436 9 * This code is distributed in the hope that it will be useful, but WITHOUT
mcimadamore@1436 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
mcimadamore@1436 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
mcimadamore@1436 12 * version 2 for more details (a copy is included in the LICENSE file that
mcimadamore@1436 13 * accompanied this code).
mcimadamore@1436 14 *
mcimadamore@1436 15 * You should have received a copy of the GNU General Public License version
mcimadamore@1436 16 * 2 along with this work; if not, write to the Free Software Foundation,
mcimadamore@1436 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
mcimadamore@1436 18 *
mcimadamore@1436 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
mcimadamore@1436 20 * or visit www.oracle.com if you need additional information or have any
mcimadamore@1436 21 * questions.
mcimadamore@1436 22 */
mcimadamore@1436 23
mcimadamore@1436 24 /*
mcimadamore@1436 25 * @test
vromero@1520 26 * @bug 8002099 8006694
mcimadamore@1436 27 * @summary Add support for intersection types in cast expression
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/timeout=360 IntersectionTypeCastTest
mcimadamore@1436 32 */
mcimadamore@1436 33
vromero@1520 34 // use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
vromero@1520 35 // see JDK-8006746
vromero@1520 36
mcimadamore@1436 37 import java.net.URI;
mcimadamore@1436 38 import java.util.Arrays;
mcimadamore@1436 39 import javax.tools.Diagnostic;
mcimadamore@1436 40 import javax.tools.JavaCompiler;
mcimadamore@1436 41 import javax.tools.JavaFileObject;
mcimadamore@1436 42 import javax.tools.SimpleJavaFileObject;
mcimadamore@1436 43 import javax.tools.ToolProvider;
mcimadamore@1436 44
vromero@1482 45 import com.sun.source.util.JavacTask;
vromero@1482 46 import com.sun.tools.javac.util.List;
vromero@1482 47 import com.sun.tools.javac.util.ListBuffer;
mcimadamore@1436 48
vromero@1482 49 public class IntersectionTypeCastTest
vromero@1482 50 extends JavacTestingAbstractThreadedTest
vromero@1482 51 implements Runnable {
mcimadamore@1436 52
mcimadamore@1436 53 interface Type {
mcimadamore@1436 54 boolean subtypeOf(Type that);
mcimadamore@1436 55 String asString();
mcimadamore@1436 56 boolean isClass();
mcimadamore@1436 57 boolean isInterface();
mcimadamore@1436 58 }
mcimadamore@1436 59
mcimadamore@1436 60 enum InterfaceKind implements Type {
mcimadamore@1436 61 A("interface A { }\n", "A", null),
mcimadamore@1436 62 B("interface B { }\n", "B", null),
mcimadamore@1436 63 C("interface C extends A { }\n", "C", A);
mcimadamore@1436 64
mcimadamore@1436 65 String declStr;
mcimadamore@1436 66 String typeStr;
mcimadamore@1436 67 InterfaceKind superInterface;
mcimadamore@1436 68
vromero@1482 69 InterfaceKind(String declStr, String typeStr,
vromero@1482 70 InterfaceKind superInterface) {
mcimadamore@1436 71 this.declStr = declStr;
mcimadamore@1436 72 this.typeStr = typeStr;
mcimadamore@1436 73 this.superInterface = superInterface;
mcimadamore@1436 74 }
mcimadamore@1436 75
mcimadamore@1436 76 @Override
mcimadamore@1436 77 public boolean subtypeOf(Type that) {
vromero@1482 78 return this == that || superInterface == that ||
vromero@1482 79 that == ClassKind.OBJECT;
mcimadamore@1436 80 }
mcimadamore@1436 81
mcimadamore@1436 82 @Override
mcimadamore@1436 83 public String asString() {
mcimadamore@1436 84 return typeStr;
mcimadamore@1436 85 }
mcimadamore@1436 86
mcimadamore@1436 87 @Override
mcimadamore@1436 88 public boolean isClass() {
mcimadamore@1436 89 return false;
mcimadamore@1436 90 }
mcimadamore@1436 91
mcimadamore@1436 92 @Override
mcimadamore@1436 93 public boolean isInterface() {
mcimadamore@1436 94 return true;
mcimadamore@1436 95 }
mcimadamore@1436 96 }
mcimadamore@1436 97
mcimadamore@1436 98 enum ClassKind implements Type {
mcimadamore@1436 99 OBJECT(null, "Object"),
vromero@1482 100 CA("#M class CA implements A { }\n", "CA",
vromero@1482 101 InterfaceKind.A),
vromero@1482 102 CB("#M class CB implements B { }\n", "CB",
vromero@1482 103 InterfaceKind.B),
vromero@1482 104 CAB("#M class CAB implements A, B { }\n", "CAB",
vromero@1482 105 InterfaceKind.A, InterfaceKind.B),
vromero@1482 106 CC("#M class CC implements C { }\n", "CC",
vromero@1482 107 InterfaceKind.C, InterfaceKind.A),
vromero@1482 108 CCA("#M class CCA implements C, A { }\n", "CCA",
vromero@1482 109 InterfaceKind.C, InterfaceKind.A),
vromero@1482 110 CCB("#M class CCB implements C, B { }\n", "CCB",
vromero@1482 111 InterfaceKind.C, InterfaceKind.A, InterfaceKind.B),
vromero@1482 112 CCAB("#M class CCAB implements C, A, B { }\n", "CCAB",
vromero@1482 113 InterfaceKind.C, InterfaceKind.A, InterfaceKind.B);
mcimadamore@1436 114
mcimadamore@1436 115 String declTemplate;
mcimadamore@1436 116 String typeStr;
mcimadamore@1436 117 List<InterfaceKind> superInterfaces;
mcimadamore@1436 118
vromero@1482 119 ClassKind(String declTemplate, String typeStr,
vromero@1482 120 InterfaceKind... superInterfaces) {
mcimadamore@1436 121 this.declTemplate = declTemplate;
mcimadamore@1436 122 this.typeStr = typeStr;
mcimadamore@1436 123 this.superInterfaces = List.from(superInterfaces);
mcimadamore@1436 124 }
mcimadamore@1436 125
mcimadamore@1436 126 String getDecl(ModifierKind mod) {
mcimadamore@1436 127 return declTemplate != null ?
mcimadamore@1436 128 declTemplate.replaceAll("#M", mod.modStr) :
mcimadamore@1436 129 "";
mcimadamore@1436 130 }
mcimadamore@1436 131
mcimadamore@1436 132 @Override
mcimadamore@1436 133 public boolean subtypeOf(Type that) {
vromero@1482 134 return this == that || superInterfaces.contains(that) ||
vromero@1482 135 that == OBJECT;
mcimadamore@1436 136 }
mcimadamore@1436 137
mcimadamore@1436 138 @Override
mcimadamore@1436 139 public String asString() {
mcimadamore@1436 140 return typeStr;
mcimadamore@1436 141 }
mcimadamore@1436 142
mcimadamore@1436 143 @Override
mcimadamore@1436 144 public boolean isClass() {
mcimadamore@1436 145 return true;
mcimadamore@1436 146 }
mcimadamore@1436 147
mcimadamore@1436 148 @Override
mcimadamore@1436 149 public boolean isInterface() {
mcimadamore@1436 150 return false;
mcimadamore@1436 151 }
mcimadamore@1436 152 }
mcimadamore@1436 153
mcimadamore@1436 154 enum ModifierKind {
mcimadamore@1436 155 NONE(""),
mcimadamore@1436 156 FINAL("final");
mcimadamore@1436 157
mcimadamore@1436 158 String modStr;
mcimadamore@1436 159
mcimadamore@1436 160 ModifierKind(String modStr) {
mcimadamore@1436 161 this.modStr = modStr;
mcimadamore@1436 162 }
mcimadamore@1436 163 }
mcimadamore@1436 164
mcimadamore@1436 165 enum CastKind {
mcimadamore@1436 166 CLASS("(#C)", 0),
mcimadamore@1436 167 INTERFACE("(#I0)", 1),
mcimadamore@1436 168 INTERSECTION2("(#C & #I0)", 1),
mcimadamore@1436 169 INTERSECTION3("(#C & #I0 & #I1)", 2);
mcimadamore@1436 170 //INTERSECTION4("(#C & #I0 & #I1 & #I2)", 3);
mcimadamore@1436 171
mcimadamore@1436 172 String castTemplate;
mcimadamore@1436 173 int interfaceBounds;
mcimadamore@1436 174
mcimadamore@1436 175 CastKind(String castTemplate, int interfaceBounds) {
mcimadamore@1436 176 this.castTemplate = castTemplate;
mcimadamore@1436 177 this.interfaceBounds = interfaceBounds;
mcimadamore@1436 178 }
mcimadamore@1436 179 }
mcimadamore@1436 180
mcimadamore@1436 181 static class CastInfo {
mcimadamore@1436 182 CastKind kind;
mcimadamore@1436 183 Type[] types;
mcimadamore@1436 184
mcimadamore@1436 185 CastInfo(CastKind kind, Type... types) {
mcimadamore@1436 186 this.kind = kind;
mcimadamore@1436 187 this.types = types;
mcimadamore@1436 188 }
mcimadamore@1436 189
mcimadamore@1436 190 String getCast() {
vromero@1482 191 String temp = kind.castTemplate.replaceAll("#C",
vromero@1482 192 types[0].asString());
mcimadamore@1436 193 for (int i = 0; i < kind.interfaceBounds ; i++) {
vromero@1482 194 temp = temp.replace(String.format("#I%d", i),
vromero@1482 195 types[i + 1].asString());
mcimadamore@1436 196 }
mcimadamore@1436 197 return temp;
mcimadamore@1436 198 }
mcimadamore@1436 199
mcimadamore@1436 200 boolean hasDuplicateTypes() {
mcimadamore@1436 201 for (int i = 0 ; i < types.length ; i++) {
mcimadamore@1436 202 for (int j = 0 ; j < types.length ; j++) {
mcimadamore@1436 203 if (i != j && types[i] == types[j]) {
mcimadamore@1436 204 return true;
mcimadamore@1436 205 }
mcimadamore@1436 206 }
mcimadamore@1436 207 }
mcimadamore@1436 208 return false;
mcimadamore@1436 209 }
mcimadamore@1436 210
mcimadamore@1436 211 boolean compatibleWith(ModifierKind mod, CastInfo that) {
mcimadamore@1436 212 for (Type t1 : types) {
mcimadamore@1436 213 for (Type t2 : that.types) {
mcimadamore@1436 214 boolean compat =
mcimadamore@1436 215 t1.subtypeOf(t2) ||
mcimadamore@1436 216 t2.subtypeOf(t1) ||
mcimadamore@1436 217 (t1.isInterface() && t2.isInterface()) || //side-cast (1)
vromero@1482 218 (mod == ModifierKind.NONE &&
vromero@1482 219 (t1.isInterface() != t2.isInterface())); //side-cast (2)
mcimadamore@1436 220 if (!compat) return false;
mcimadamore@1436 221 }
mcimadamore@1436 222 }
mcimadamore@1436 223 return true;
mcimadamore@1436 224 }
mcimadamore@1436 225 }
mcimadamore@1436 226
mcimadamore@1436 227 public static void main(String... args) throws Exception {
mcimadamore@1436 228 for (ModifierKind mod : ModifierKind.values()) {
mcimadamore@1436 229 for (CastInfo cast1 : allCastInfo()) {
mcimadamore@1436 230 for (CastInfo cast2 : allCastInfo()) {
vromero@1482 231 pool.execute(
vromero@1482 232 new IntersectionTypeCastTest(mod, cast1, cast2));
mcimadamore@1436 233 }
mcimadamore@1436 234 }
mcimadamore@1436 235 }
vromero@1482 236 checkAfterExec();
mcimadamore@1436 237 }
mcimadamore@1436 238
mcimadamore@1436 239 static List<CastInfo> allCastInfo() {
mcimadamore@1436 240 ListBuffer<CastInfo> buf = ListBuffer.lb();
mcimadamore@1436 241 for (CastKind kind : CastKind.values()) {
mcimadamore@1436 242 for (ClassKind clazz : ClassKind.values()) {
mcimadamore@1436 243 if (kind == CastKind.INTERFACE && clazz != ClassKind.OBJECT) {
mcimadamore@1436 244 continue;
mcimadamore@1436 245 } else if (kind.interfaceBounds == 0) {
mcimadamore@1436 246 buf.append(new CastInfo(kind, clazz));
mcimadamore@1436 247 continue;
mcimadamore@1436 248 } else {
mcimadamore@1436 249 for (InterfaceKind intf1 : InterfaceKind.values()) {
mcimadamore@1436 250 if (kind.interfaceBounds == 1) {
mcimadamore@1436 251 buf.append(new CastInfo(kind, clazz, intf1));
mcimadamore@1436 252 continue;
mcimadamore@1436 253 } else {
mcimadamore@1436 254 for (InterfaceKind intf2 : InterfaceKind.values()) {
mcimadamore@1436 255 if (kind.interfaceBounds == 2) {
vromero@1482 256 buf.append(
vromero@1482 257 new CastInfo(kind, clazz, intf1, intf2));
mcimadamore@1436 258 continue;
mcimadamore@1436 259 } else {
mcimadamore@1436 260 for (InterfaceKind intf3 : InterfaceKind.values()) {
vromero@1482 261 buf.append(
vromero@1482 262 new CastInfo(kind, clazz, intf1,
vromero@1482 263 intf2, intf3));
mcimadamore@1436 264 continue;
mcimadamore@1436 265 }
mcimadamore@1436 266 }
mcimadamore@1436 267 }
mcimadamore@1436 268 }
mcimadamore@1436 269 }
mcimadamore@1436 270 }
mcimadamore@1436 271 }
mcimadamore@1436 272 }
mcimadamore@1436 273 return buf.toList();
mcimadamore@1436 274 }
mcimadamore@1436 275
mcimadamore@1436 276 ModifierKind mod;
mcimadamore@1436 277 CastInfo cast1, cast2;
mcimadamore@1436 278 JavaSource source;
mcimadamore@1436 279 DiagnosticChecker diagChecker;
mcimadamore@1436 280
mcimadamore@1436 281 IntersectionTypeCastTest(ModifierKind mod, CastInfo cast1, CastInfo cast2) {
mcimadamore@1436 282 this.mod = mod;
mcimadamore@1436 283 this.cast1 = cast1;
mcimadamore@1436 284 this.cast2 = cast2;
mcimadamore@1436 285 this.source = new JavaSource();
mcimadamore@1436 286 this.diagChecker = new DiagnosticChecker();
mcimadamore@1436 287 }
mcimadamore@1436 288
vromero@1482 289 @Override
vromero@1482 290 public void run() {
vromero@1482 291 final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
vromero@1482 292
vromero@1482 293 JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), diagChecker,
mcimadamore@1511 294 null, null, Arrays.asList(source));
vromero@1482 295 try {
vromero@1482 296 ct.analyze();
vromero@1482 297 } catch (Throwable ex) {
vromero@1482 298 throw new AssertionError("Error thrown when compiling the following code:\n" +
vromero@1482 299 source.getCharContent(true));
vromero@1482 300 }
vromero@1482 301 check();
vromero@1482 302 }
vromero@1482 303
mcimadamore@1436 304 class JavaSource extends SimpleJavaFileObject {
mcimadamore@1436 305
mcimadamore@1436 306 String bodyTemplate = "class Test {\n" +
mcimadamore@1436 307 " void test() {\n" +
mcimadamore@1436 308 " Object o = #C1#C2null;\n" +
mcimadamore@1436 309 " } }";
mcimadamore@1436 310
mcimadamore@1436 311 String source = "";
mcimadamore@1436 312
mcimadamore@1436 313 public JavaSource() {
mcimadamore@1436 314 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
mcimadamore@1436 315 for (ClassKind ck : ClassKind.values()) {
mcimadamore@1436 316 source += ck.getDecl(mod);
mcimadamore@1436 317 }
mcimadamore@1436 318 for (InterfaceKind ik : InterfaceKind.values()) {
mcimadamore@1436 319 source += ik.declStr;
mcimadamore@1436 320 }
vromero@1482 321 source += bodyTemplate.replaceAll("#C1", cast1.getCast()).
vromero@1482 322 replaceAll("#C2", cast2.getCast());
mcimadamore@1436 323 }
mcimadamore@1436 324
mcimadamore@1436 325 @Override
mcimadamore@1436 326 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
mcimadamore@1436 327 return source;
mcimadamore@1436 328 }
mcimadamore@1436 329 }
mcimadamore@1436 330
vromero@1482 331 void check() {
vromero@1482 332 checkCount.incrementAndGet();
mcimadamore@1436 333
vromero@1482 334 boolean errorExpected = cast1.hasDuplicateTypes() ||
vromero@1482 335 cast2.hasDuplicateTypes();
mcimadamore@1436 336
mcimadamore@1436 337 errorExpected |= !cast2.compatibleWith(mod, cast1);
mcimadamore@1436 338
mcimadamore@1436 339 if (errorExpected != diagChecker.errorFound) {
mcimadamore@1436 340 throw new Error("invalid diagnostics for source:\n" +
mcimadamore@1436 341 source.getCharContent(true) +
mcimadamore@1436 342 "\nFound error: " + diagChecker.errorFound +
mcimadamore@1436 343 "\nExpected error: " + errorExpected);
mcimadamore@1436 344 }
mcimadamore@1436 345 }
mcimadamore@1436 346
vromero@1482 347 static class DiagnosticChecker
vromero@1482 348 implements javax.tools.DiagnosticListener<JavaFileObject> {
mcimadamore@1436 349
mcimadamore@1436 350 boolean errorFound;
mcimadamore@1436 351
mcimadamore@1436 352 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
mcimadamore@1436 353 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
mcimadamore@1436 354 errorFound = true;
mcimadamore@1436 355 }
mcimadamore@1436 356 }
mcimadamore@1436 357 }
vromero@1482 358
mcimadamore@1436 359 }

mercurial