test/tools/javac/types/GenericTypeWellFormednessTest.java

Wed, 06 Apr 2011 20:33:44 -0700

author
ohair
date
Wed, 06 Apr 2011 20:33:44 -0700
changeset 962
0ff2bbd38f10
parent 821
c8d312dd17bc
child 2525
2eb010b6cb22
permissions
-rw-r--r--

7033660: Update copyright year to 2011 on any files changed in 2011
Reviewed-by: dholmes

mcimadamore@821 1 /*
ohair@962 2 * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
mcimadamore@821 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
mcimadamore@821 4 *
mcimadamore@821 5 * This code is free software; you can redistribute it and/or modify it
mcimadamore@821 6 * under the terms of the GNU General Public License version 2 only, as
mcimadamore@821 7 * published by the Free Software Foundation.
mcimadamore@821 8 *
mcimadamore@821 9 * This code is distributed in the hope that it will be useful, but WITHOUT
mcimadamore@821 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
mcimadamore@821 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
mcimadamore@821 12 * version 2 for more details (a copy is included in the LICENSE file that
mcimadamore@821 13 * accompanied this code).
mcimadamore@821 14 *
mcimadamore@821 15 * You should have received a copy of the GNU General Public License version
mcimadamore@821 16 * 2 along with this work; if not, write to the Free Software Foundation,
mcimadamore@821 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
mcimadamore@821 18 *
mcimadamore@821 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
mcimadamore@821 20 * or visit www.oracle.com if you need additional information or have any
mcimadamore@821 21 * questions.
mcimadamore@821 22 */
mcimadamore@821 23
mcimadamore@821 24 /*
mcimadamore@821 25 * @test
mcimadamore@821 26 * @bug 7007432 7006109
mcimadamore@821 27 * @summary Test generic types well-formedness
mcimadamore@821 28 * @author mcimadamore
mcimadamore@821 29 * @library .
mcimadamore@821 30 * @run main GenericTypeWellFormednessTest
mcimadamore@821 31 */
mcimadamore@821 32
mcimadamore@821 33 import com.sun.tools.javac.code.BoundKind;
mcimadamore@821 34 import com.sun.tools.javac.code.Type;
mcimadamore@821 35 import com.sun.tools.javac.code.Type.*;
mcimadamore@821 36 import com.sun.tools.javac.code.Symbol;
mcimadamore@821 37 import com.sun.tools.javac.code.Symbol.*;
mcimadamore@821 38 import java.lang.reflect.Array;
mcimadamore@821 39
mcimadamore@821 40 /**
mcimadamore@821 41 * Check parameterized type well-formedness. This test executes a number of checks
mcimadamore@821 42 * in order to establish as to whether an instantiation of a generic type conforms
mcimadamore@821 43 * to the generic class' declared bounds.
mcimadamore@821 44 */
mcimadamore@821 45 public class GenericTypeWellFormednessTest extends TypeHarness {
mcimadamore@821 46
mcimadamore@821 47 static int executedCount = 0;
mcimadamore@821 48 static int ignoredCount = 0;
mcimadamore@821 49
mcimadamore@821 50 InstantiableType[] rows;
mcimadamore@821 51 Type[] columns;
mcimadamore@821 52
mcimadamore@821 53 static class InstantiableType {
mcimadamore@821 54 protected Type type;
mcimadamore@821 55
mcimadamore@821 56 public InstantiableType(Type type) {
mcimadamore@821 57 this.type = type;
mcimadamore@821 58 }
mcimadamore@821 59
mcimadamore@821 60 Type inst(Type clazz) {
mcimadamore@821 61 return type;
mcimadamore@821 62 }
mcimadamore@821 63 }
mcimadamore@821 64
mcimadamore@821 65 enum Result {
mcimadamore@821 66 /* generic type is well-formed w.r.t. declared bounds */
mcimadamore@821 67 OK(true),
mcimadamore@821 68 /* generic type is not well-formed w.r.t. declared bounds */
mcimadamore@821 69 FAIL(false),
mcimadamore@821 70 /* generic type is not well-formed w.r.t. declared bounds according to the JLS 3rd,
mcimadamore@821 71 * but javac allows it (spec for generic type well-formedness is overly restrictive)
mcimadamore@821 72 * See regression test test/tools/generics/wildcards/T5097548.java
mcimadamore@821 73 */
mcimadamore@821 74 IGNORE(false);
mcimadamore@821 75
mcimadamore@821 76 boolean value;
mcimadamore@821 77
mcimadamore@821 78 Result(boolean value) {
mcimadamore@821 79 this.value = value;
mcimadamore@821 80 }
mcimadamore@821 81 }
mcimadamore@821 82
mcimadamore@821 83 static final Result T = Result.OK;
mcimadamore@821 84 static final Result F = Result.FAIL;
mcimadamore@821 85 static final Result I = Result.IGNORE;
mcimadamore@821 86
mcimadamore@821 87 /*is a type in 'rows' a valid instantiation for the generic class in 'col' ? */
mcimadamore@821 88 Result[][] isValidInstantiation = {
mcimadamore@821 89 //Foo<X>, Foo<X ext Object>, Foo<X ext Number>, Foo<X ext Foo<X>>, Foo<X ext Foo<+X>>, Foo<X ext Foo<-X>>, Foo<X ext Foo<?>>
mcimadamore@821 90 /*Foo<Object>*/ { T , T , F , F , F , F , F },
mcimadamore@821 91 /*Foo<Number>*/ { T , T , T , F , F , F , F },
mcimadamore@821 92 /*Foo<Integer>*/ { T , T , T , F , F , F , F },
mcimadamore@821 93 /*Foo<Double>*/ { T , T , T , F , F , F , F },
mcimadamore@821 94 /*Foo<String>*/ { T , T , F , F , F , F , F },
mcimadamore@821 95 /*Foo<X1>*/ { T , T , F , F , F , F , F },
mcimadamore@821 96 /*Foo<X2>*/ { T , T , T , F , F , F , F },
mcimadamore@821 97 /*Foo<X3>*/ { T , T , T , F , F , F , F },
mcimadamore@821 98 /*Foo<X4>*/ { T , T , T , F , F , F , F },
mcimadamore@821 99 /*Foo<X5>*/ { T , T , F , F , F , F , F },
mcimadamore@821 100 /*Foo<X6>*/ { T , T , F , T , T , T , T },
mcimadamore@821 101 /*Foo<+Object>*/ { T , T , I , I , I , I , I },
mcimadamore@821 102 /*Foo<+Number>*/ { T , T , T , F , F , F , F },
mcimadamore@821 103 /*Foo<+Integer>*/{ T , T , T , F , F , F , F },
mcimadamore@821 104 /*Foo<+Double>*/ { T , T , T , F , F , F , F },
mcimadamore@821 105 /*Foo<+String>*/ { T , T , F , F , F , F , F },
mcimadamore@821 106 /*Foo<+X1>*/ { T , T , F , F , F , F , F },
mcimadamore@821 107 /*Foo<+X2>*/ { T , T , T , F , F , F , F },
mcimadamore@821 108 /*Foo<+X3>*/ { T , T , T , F , F , F , F },
mcimadamore@821 109 /*Foo<+X4>*/ { T , T , T , F , F , F , F },
mcimadamore@821 110 /*Foo<+X5>*/ { T , T , F , F , F , F , F },
mcimadamore@821 111 /*Foo<+X6>*/ { T , T , F , T , T , I , T },
mcimadamore@821 112 /*Foo<-Object>*/ { T , T , F , F , F , F , F },
mcimadamore@821 113 /*Foo<-Number>*/ { T , T , T , F , F , F , F },
mcimadamore@821 114 /*Foo<-Integer>*/{ T , T , T , F , F , F , F },
mcimadamore@821 115 /*Foo<-Double>*/ { T , T , T , F , F , F , F },
mcimadamore@821 116 /*Foo<-String>*/ { T , T , F , F , F , F , F },
mcimadamore@821 117 /*Foo<-X1>*/ { T , T , I , I , I , I , I },
mcimadamore@821 118 /*Foo<-X2>*/ { T , T , I , F , F , F , F },
mcimadamore@821 119 /*Foo<-X3>*/ { T , T , I , F , F , F , F },
mcimadamore@821 120 /*Foo<-X4>*/ { T , T , I , F , F , F , F },
mcimadamore@821 121 /*Foo<-X5>*/ { T , T , I , F , F , F , F },
mcimadamore@821 122 /*Foo<-X6>*/ { T , T , F , T , I , I , T },
mcimadamore@821 123 /*Foo<?>*/ { T , T , T , T , T , T , T }};
mcimadamore@821 124
mcimadamore@821 125 GenericTypeWellFormednessTest() {
mcimadamore@821 126 InstantiableType[] basicTypes = {
mcimadamore@821 127 new InstantiableType(predef.objectType),
mcimadamore@821 128 new InstantiableType(NumberType()),
mcimadamore@821 129 new InstantiableType(box(predef.intType)),
mcimadamore@821 130 new InstantiableType(box(predef.doubleType)),
mcimadamore@821 131 new InstantiableType(predef.stringType) };
mcimadamore@821 132
mcimadamore@821 133 InstantiableType[] typeVars = new InstantiableType[basicTypes.length + 1];
mcimadamore@821 134 for (int i = 0 ; i < basicTypes.length ; i++) {
mcimadamore@821 135 typeVars[i] = new InstantiableType(fac.TypeVariable(basicTypes[i].type));
mcimadamore@821 136 }
mcimadamore@821 137 typeVars[typeVars.length - 1] = new InstantiableType(null) {
mcimadamore@821 138 Type inst(Type clazz) {
mcimadamore@821 139 TypeVar tvar = fac.TypeVariable();
mcimadamore@821 140 tvar.bound = subst(clazz, Mapping(clazz.getTypeArguments().head, tvar));
mcimadamore@821 141 return tvar;
mcimadamore@821 142 }
mcimadamore@821 143 };
mcimadamore@821 144
mcimadamore@821 145 InstantiableType[] typeArgs = join(InstantiableType.class, basicTypes, typeVars);
mcimadamore@821 146
mcimadamore@821 147 InstantiableType[] invariantTypes = new InstantiableType[typeArgs.length];
mcimadamore@821 148 for (int i = 0 ; i < typeArgs.length ; i++) {
mcimadamore@821 149 final InstantiableType type1 = typeArgs[i];
mcimadamore@821 150 invariantTypes[i] = new InstantiableType(typeArgs[i].type) {
mcimadamore@821 151 Type inst(Type clazz) {
mcimadamore@821 152 return subst(clazz, Mapping(clazz.getTypeArguments().head, type1.inst(clazz)));
mcimadamore@821 153 }
mcimadamore@821 154 };
mcimadamore@821 155 }
mcimadamore@821 156
mcimadamore@821 157 InstantiableType[] covariantTypes = new InstantiableType[typeArgs.length];
mcimadamore@821 158 for (int i = 0 ; i < typeArgs.length ; i++) {
mcimadamore@821 159 final InstantiableType type1 = typeArgs[i];
mcimadamore@821 160 covariantTypes[i] = new InstantiableType(null) {
mcimadamore@821 161 Type inst(Type clazz) {
mcimadamore@821 162 Type t = fac.Wildcard(BoundKind.EXTENDS, type1.inst(clazz));
mcimadamore@821 163 return subst(clazz, Mapping(clazz.getTypeArguments().head, t));
mcimadamore@821 164 }
mcimadamore@821 165 };
mcimadamore@821 166 }
mcimadamore@821 167
mcimadamore@821 168 InstantiableType[] contravariantTypes = new InstantiableType[typeArgs.length];
mcimadamore@821 169 for (int i = 0 ; i < typeArgs.length ; i++) {
mcimadamore@821 170 final InstantiableType type1 = typeArgs[i];
mcimadamore@821 171 contravariantTypes[i] = new InstantiableType(null) {
mcimadamore@821 172 Type inst(Type clazz) {
mcimadamore@821 173 Type t = fac.Wildcard(BoundKind.SUPER, type1.inst(clazz));
mcimadamore@821 174 return subst(clazz, Mapping(clazz.getTypeArguments().head, t));
mcimadamore@821 175 }
mcimadamore@821 176 };
mcimadamore@821 177 }
mcimadamore@821 178
mcimadamore@821 179 InstantiableType[] bivariantTypes = {
mcimadamore@821 180 new InstantiableType(fac.Wildcard(BoundKind.UNBOUND, predef.objectType)) {
mcimadamore@821 181 Type inst(Type clazz) {
mcimadamore@821 182 return subst(clazz, Mapping(clazz.getTypeArguments().head, type));
mcimadamore@821 183 }
mcimadamore@821 184 }
mcimadamore@821 185 };
mcimadamore@821 186
mcimadamore@821 187 rows = join(InstantiableType.class, invariantTypes, covariantTypes, contravariantTypes, bivariantTypes);
mcimadamore@821 188
mcimadamore@821 189 Type tv1 = fac.TypeVariable();
mcimadamore@821 190 Type decl1 = fac.Class(tv1);
mcimadamore@821 191
mcimadamore@821 192 Type tv2 = fac.TypeVariable(predef.objectType);
mcimadamore@821 193 Type decl2 = fac.Class(tv2);
mcimadamore@821 194
mcimadamore@821 195 Type tv3 = fac.TypeVariable(NumberType());
mcimadamore@821 196 Type decl3 = fac.Class(tv3);
mcimadamore@821 197
mcimadamore@821 198 TypeVar tv4 = fac.TypeVariable();
mcimadamore@821 199 Type decl4 = fac.Class(tv4);
mcimadamore@821 200 tv4.bound = decl4;
mcimadamore@821 201 tv4.tsym.name = predef.exceptionType.tsym.name;
mcimadamore@821 202
mcimadamore@821 203 TypeVar tv5 = fac.TypeVariable();
mcimadamore@821 204 Type decl5 = fac.Class(tv5);
mcimadamore@821 205 tv5.bound = subst(decl5, Mapping(tv5, fac.Wildcard(BoundKind.EXTENDS, tv5)));
mcimadamore@821 206
mcimadamore@821 207 TypeVar tv6 = fac.TypeVariable();
mcimadamore@821 208 Type decl6 = fac.Class(tv6);
mcimadamore@821 209 tv6.bound = subst(decl6, Mapping(tv6, fac.Wildcard(BoundKind.SUPER, tv6)));
mcimadamore@821 210
mcimadamore@821 211 TypeVar tv7 = fac.TypeVariable();
mcimadamore@821 212 Type decl7 = fac.Class(tv7);
mcimadamore@821 213 tv7.bound = subst(decl7, Mapping(tv7, fac.Wildcard(BoundKind.UNBOUND, predef.objectType)));
mcimadamore@821 214
mcimadamore@821 215 columns = new Type[] {
mcimadamore@821 216 decl1, decl2, decl3, decl4, decl5, decl6, decl7
mcimadamore@821 217 };
mcimadamore@821 218 }
mcimadamore@821 219
mcimadamore@821 220 void test() {
mcimadamore@821 221 for (int i = 0; i < rows.length ; i++) {
mcimadamore@821 222 for (int j = 0; j < columns.length ; j++) {
mcimadamore@821 223 Type decl = columns[j];
mcimadamore@821 224 Type inst = rows[i].inst(decl);
mcimadamore@821 225 if (isValidInstantiation[i][j] != Result.IGNORE) {
mcimadamore@821 226 executedCount++;
mcimadamore@821 227 assertValidGenericType(inst, isValidInstantiation[i][j].value);
mcimadamore@821 228 } else {
mcimadamore@821 229 ignoredCount++;
mcimadamore@821 230 }
mcimadamore@821 231 }
mcimadamore@821 232 }
mcimadamore@821 233 }
mcimadamore@821 234
mcimadamore@821 235 Type NumberType() {
mcimadamore@821 236 Symbol s = box(predef.intType).tsym;
mcimadamore@821 237 s.complete();
mcimadamore@821 238 return ((ClassType)s.type).supertype_field;
mcimadamore@821 239 }
mcimadamore@821 240
mcimadamore@821 241 @SuppressWarnings("unchecked")
mcimadamore@821 242 <T> T[] join(Class<T> type, T[]... args) {
mcimadamore@821 243 int totalLength = 0;
mcimadamore@821 244 for (T[] arr : args) {
mcimadamore@821 245 totalLength += arr.length;
mcimadamore@821 246 }
mcimadamore@821 247 T[] new_arr = (T[])Array.newInstance(type, totalLength);
mcimadamore@821 248 int idx = 0;
mcimadamore@821 249 for (T[] arr : args) {
mcimadamore@821 250 System.arraycopy(arr, 0, new_arr, idx, arr.length);
mcimadamore@821 251 idx += arr.length;
mcimadamore@821 252 }
mcimadamore@821 253 return new_arr;
mcimadamore@821 254 }
mcimadamore@821 255
mcimadamore@821 256 public static void main(String[] args) {
mcimadamore@821 257 new GenericTypeWellFormednessTest().test();
mcimadamore@821 258 System.out.println("Executed checks : " + executedCount);
mcimadamore@821 259 System.out.println("Ignored checks : " + ignoredCount);
mcimadamore@821 260 }
mcimadamore@821 261 }

mercurial