test/tools/javap/classfile/6888367/T6888367.java

Sat, 07 Nov 2020 10:30:02 +0800

author
aoqi
date
Sat, 07 Nov 2020 10:30:02 +0800
changeset 3938
93012e2a5d1d
parent 2525
2eb010b6cb22
permissions
-rw-r--r--

Added tag mips-jdk8u275-b01 for changeset eb6ee6a5f2fe

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 */
aoqi@0 23
aoqi@0 24 import java.io.*;
aoqi@0 25 import java.net.*;
aoqi@0 26 import java.util.*;
aoqi@0 27 import com.sun.tools.classfile.*;
aoqi@0 28 import com.sun.tools.classfile.Type.ArrayType;
aoqi@0 29 import com.sun.tools.classfile.Type.ClassSigType;
aoqi@0 30 import com.sun.tools.classfile.Type.ClassType;
aoqi@0 31 import com.sun.tools.classfile.Type.MethodType;
aoqi@0 32 import com.sun.tools.classfile.Type.SimpleType;
aoqi@0 33 import com.sun.tools.classfile.Type.TypeParamType;
aoqi@0 34 import com.sun.tools.classfile.Type.WildcardType;
aoqi@0 35
aoqi@0 36 /*
aoqi@0 37 * @test
aoqi@0 38 * @bug 6888367
aoqi@0 39 * @summary classfile library parses signature attributes incorrectly
aoqi@0 40 */
aoqi@0 41
aoqi@0 42 /*
aoqi@0 43 * This test is a pretty detailed test both of javac signature generation and classfile
aoqi@0 44 * signature parsing. The first part of the test tests all the examples given in the
aoqi@0 45 * second part of the test. Each example comes with one or two annotations, @Desc, @Sig,
aoqi@0 46 * for the descriptor and signature of the annotated declaration. Annotations are
aoqi@0 47 * provided whenever the annotated item is expected to have a corresponding value.
aoqi@0 48 * Each annotation has two argument values. The first arg is the expected value of the
aoqi@0 49 * descriptor/signature as found in the class file. This value is mostly for documentation
aoqi@0 50 * purposes in reading the test. The second value is the rendering of the descriptor or
aoqi@0 51 * signature using a custom Type visitor that explicitly includes an indication of the
aoqi@0 52 * Type classes being used to represent the descriptor/signature. Thus we test
aoqi@0 53 * that the descriptor/signature is being parsed into the expected type tree structure.
aoqi@0 54 */
aoqi@0 55 public class T6888367 {
aoqi@0 56
aoqi@0 57 public static void main(String... args) throws Exception {
aoqi@0 58 new T6888367().run();
aoqi@0 59 }
aoqi@0 60
aoqi@0 61 public void run() throws Exception {
aoqi@0 62 ClassFile cf = getClassFile("Test");
aoqi@0 63
aoqi@0 64 testFields(cf);
aoqi@0 65 testMethods(cf);
aoqi@0 66 testInnerClasses(cf); // recursive
aoqi@0 67
aoqi@0 68 if (errors > 0)
aoqi@0 69 throw new Exception(errors + " errors found");
aoqi@0 70 }
aoqi@0 71
aoqi@0 72 void testFields(ClassFile cf) throws Exception {
aoqi@0 73 String cn = cf.getName();
aoqi@0 74 ConstantPool cp = cf.constant_pool;
aoqi@0 75 for (Field f: cf.fields) {
aoqi@0 76 test("field " + cn + "." + f.getName(cp), f.descriptor, f.attributes, cp);
aoqi@0 77 }
aoqi@0 78 }
aoqi@0 79
aoqi@0 80 void testMethods(ClassFile cf) throws Exception {
aoqi@0 81 String cn = cf.getName();
aoqi@0 82 ConstantPool cp = cf.constant_pool;
aoqi@0 83 for (Method m: cf.methods) {
aoqi@0 84 test("method " + cn + "." + m.getName(cp), m.descriptor, m.attributes, cp);
aoqi@0 85 }
aoqi@0 86 }
aoqi@0 87
aoqi@0 88 void testInnerClasses(ClassFile cf) throws Exception {
aoqi@0 89 ConstantPool cp = cf.constant_pool;
aoqi@0 90 InnerClasses_attribute ic =
aoqi@0 91 (InnerClasses_attribute) cf.attributes.get(Attribute.InnerClasses);
aoqi@0 92 for (InnerClasses_attribute.Info info: ic.classes) {
aoqi@0 93 String outerClassName = cp.getClassInfo(info.outer_class_info_index).getName();
aoqi@0 94 if (!outerClassName.equals(cf.getName())) {
aoqi@0 95 continue;
aoqi@0 96 }
aoqi@0 97 String innerClassName = cp.getClassInfo(info.inner_class_info_index).getName();
aoqi@0 98 ClassFile icf = getClassFile(innerClassName);
aoqi@0 99 test("class " + innerClassName, null, icf.attributes, icf.constant_pool);
aoqi@0 100 testInnerClasses(icf);
aoqi@0 101 }
aoqi@0 102 }
aoqi@0 103
aoqi@0 104 void test(String name, Descriptor desc, Attributes attrs, ConstantPool cp)
aoqi@0 105 throws Exception {
aoqi@0 106 AnnotValues d = getDescValue(attrs, cp);
aoqi@0 107 AnnotValues s = getSigValue(attrs, cp);
aoqi@0 108 if (d == null && s == null) // not a test field or method if no @Desc or @Sig given
aoqi@0 109 return;
aoqi@0 110
aoqi@0 111 System.err.println(name);
aoqi@0 112
aoqi@0 113 if (desc != null) {
aoqi@0 114 System.err.println(" descriptor: " + desc.getValue(cp));
aoqi@0 115 checkEqual(d.raw, desc.getValue(cp));
aoqi@0 116 Type dt = new Signature(desc.index).getType(cp);
aoqi@0 117 checkEqual(d.type, tp.print(dt));
aoqi@0 118 }
aoqi@0 119
aoqi@0 120 Signature_attribute sa = (Signature_attribute) attrs.get(Attribute.Signature);
aoqi@0 121 if (sa != null)
aoqi@0 122 System.err.println(" signature: " + sa.getSignature(cp));
aoqi@0 123
aoqi@0 124 if (s != null || sa != null) {
aoqi@0 125 if (s != null && sa != null) {
aoqi@0 126 checkEqual(s.raw, sa.getSignature(cp));
aoqi@0 127 Type st = new Signature(sa.signature_index).getType(cp);
aoqi@0 128 checkEqual(s.type, tp.print(st));
aoqi@0 129 } else if (s != null)
aoqi@0 130 error("@Sig annotation found but not Signature attribute");
aoqi@0 131 else
aoqi@0 132 error("Signature attribute found but no @Sig annotation");
aoqi@0 133 }
aoqi@0 134
aoqi@0 135 System.err.println();
aoqi@0 136 }
aoqi@0 137
aoqi@0 138
aoqi@0 139 ClassFile getClassFile(String name) throws IOException, ConstantPoolException {
aoqi@0 140 URL url = getClass().getResource(name + ".class");
aoqi@0 141 InputStream in = url.openStream();
aoqi@0 142 try {
aoqi@0 143 return ClassFile.read(in);
aoqi@0 144 } finally {
aoqi@0 145 in.close();
aoqi@0 146 }
aoqi@0 147 }
aoqi@0 148
aoqi@0 149 AnnotValues getDescValue(Attributes attrs, ConstantPool cp) throws Exception {
aoqi@0 150 return getAnnotValues(Desc.class.getName(), attrs, cp);
aoqi@0 151 }
aoqi@0 152
aoqi@0 153 AnnotValues getSigValue(Attributes attrs, ConstantPool cp) throws Exception {
aoqi@0 154 return getAnnotValues(Sig.class.getName(), attrs, cp);
aoqi@0 155 }
aoqi@0 156
aoqi@0 157 static class AnnotValues {
aoqi@0 158 AnnotValues(String raw, String type) {
aoqi@0 159 this.raw = raw;
aoqi@0 160 this.type = type;
aoqi@0 161 }
aoqi@0 162 final String raw;
aoqi@0 163 final String type;
aoqi@0 164 }
aoqi@0 165
aoqi@0 166 AnnotValues getAnnotValues(String annotName, Attributes attrs, ConstantPool cp)
aoqi@0 167 throws Exception {
aoqi@0 168 RuntimeInvisibleAnnotations_attribute annots =
aoqi@0 169 (RuntimeInvisibleAnnotations_attribute)attrs.get(Attribute.RuntimeInvisibleAnnotations);
aoqi@0 170 if (annots != null) {
aoqi@0 171 for (Annotation a: annots.annotations) {
aoqi@0 172 if (cp.getUTF8Value(a.type_index).equals("L" + annotName + ";")) {
aoqi@0 173 Annotation.Primitive_element_value pv0 =
aoqi@0 174 (Annotation.Primitive_element_value) a.element_value_pairs[0].value;
aoqi@0 175 Annotation.Primitive_element_value pv1 =
aoqi@0 176 (Annotation.Primitive_element_value) a.element_value_pairs[1].value;
aoqi@0 177 return new AnnotValues(
aoqi@0 178 cp.getUTF8Value(pv0.const_value_index),
aoqi@0 179 cp.getUTF8Value(pv1.const_value_index));
aoqi@0 180 }
aoqi@0 181 }
aoqi@0 182 }
aoqi@0 183 return null;
aoqi@0 184
aoqi@0 185 }
aoqi@0 186
aoqi@0 187 void checkEqual(String expect, String found) {
aoqi@0 188 if (!(expect == null ? found == null : expect.equals(found))) {
aoqi@0 189 System.err.println("expected: " + expect);
aoqi@0 190 System.err.println(" found: " + found);
aoqi@0 191 error("unexpected values found");
aoqi@0 192 }
aoqi@0 193 }
aoqi@0 194
aoqi@0 195 void error(String msg) {
aoqi@0 196 System.err.println("error: " + msg);
aoqi@0 197 errors++;
aoqi@0 198 }
aoqi@0 199
aoqi@0 200 int errors;
aoqi@0 201
aoqi@0 202 TypePrinter tp = new TypePrinter();
aoqi@0 203
aoqi@0 204 class TypePrinter implements Type.Visitor<String,Void> {
aoqi@0 205 String print(Type t) {
aoqi@0 206 return t == null ? null : t.accept(this, null);
aoqi@0 207 }
aoqi@0 208 String print(String pre, List<? extends Type> ts, String post) {
aoqi@0 209 if (ts == null)
aoqi@0 210 return null;
aoqi@0 211 StringBuilder sb = new StringBuilder();
aoqi@0 212 sb.append(pre);
aoqi@0 213 String sep = "";
aoqi@0 214 for (Type t: ts) {
aoqi@0 215 sb.append(sep);
aoqi@0 216 sb.append(print(t));
aoqi@0 217 sep = ",";
aoqi@0 218 }
aoqi@0 219 sb.append(post);
aoqi@0 220 return sb.toString();
aoqi@0 221 }
aoqi@0 222
aoqi@0 223 public String visitSimpleType(SimpleType type, Void p) {
aoqi@0 224 return "S{" + type.name + "}";
aoqi@0 225 }
aoqi@0 226
aoqi@0 227 public String visitArrayType(ArrayType type, Void p) {
aoqi@0 228 return "A{" + print(type.elemType) + "}";
aoqi@0 229 }
aoqi@0 230
aoqi@0 231 public String visitMethodType(MethodType type, Void p) {
aoqi@0 232 StringBuilder sb = new StringBuilder();
aoqi@0 233 sb.append("M{");
aoqi@0 234 if (type.typeParamTypes != null)
aoqi@0 235 sb.append(print("<", type.typeParamTypes, ">"));
aoqi@0 236 sb.append(print(type.returnType));
aoqi@0 237 sb.append(print("(", type.paramTypes, ")"));
aoqi@0 238 if (type.throwsTypes != null)
aoqi@0 239 sb.append(print("", type.throwsTypes, ""));
aoqi@0 240 sb.append("}");
aoqi@0 241 return sb.toString();
aoqi@0 242 }
aoqi@0 243
aoqi@0 244 public String visitClassSigType(ClassSigType type, Void p) {
aoqi@0 245 StringBuilder sb = new StringBuilder();
aoqi@0 246 sb.append("CS{");
aoqi@0 247 if (type.typeParamTypes != null)
aoqi@0 248 sb.append(print("<", type.typeParamTypes, ">"));
aoqi@0 249 sb.append(print(type.superclassType));
aoqi@0 250 if (type.superinterfaceTypes != null)
aoqi@0 251 sb.append(print("i(", type.superinterfaceTypes, ")"));
aoqi@0 252 sb.append("}");
aoqi@0 253 return sb.toString();
aoqi@0 254 }
aoqi@0 255
aoqi@0 256 public String visitClassType(ClassType type, Void p) {
aoqi@0 257 StringBuilder sb = new StringBuilder();
aoqi@0 258 sb.append("C{");
aoqi@0 259 if (type.outerType != null) {
aoqi@0 260 sb.append(print(type.outerType));
aoqi@0 261 sb.append(".");
aoqi@0 262 }
aoqi@0 263 sb.append(type.name);
aoqi@0 264 if (type.typeArgs != null)
aoqi@0 265 sb.append(print("<", type.typeArgs, ">"));
aoqi@0 266 sb.append("}");
aoqi@0 267 return sb.toString();
aoqi@0 268 }
aoqi@0 269
aoqi@0 270 public String visitTypeParamType(TypeParamType type, Void p) {
aoqi@0 271 StringBuilder sb = new StringBuilder();
aoqi@0 272 sb.append("TA{");
aoqi@0 273 sb.append(type.name);
aoqi@0 274 if (type.classBound != null) {
aoqi@0 275 sb.append(":c");
aoqi@0 276 sb.append(print(type.classBound));
aoqi@0 277 }
aoqi@0 278 if (type.interfaceBounds != null)
aoqi@0 279 sb.append(print(":i", type.interfaceBounds, ""));
aoqi@0 280 sb.append("}");
aoqi@0 281 return sb.toString();
aoqi@0 282 }
aoqi@0 283
aoqi@0 284 public String visitWildcardType(WildcardType type, Void p) {
aoqi@0 285 switch (type.kind) {
aoqi@0 286 case UNBOUNDED:
aoqi@0 287 return "W{?}";
aoqi@0 288 case EXTENDS:
aoqi@0 289 return "W{e," + print(type.boundType) + "}";
aoqi@0 290 case SUPER:
aoqi@0 291 return "W{s," + print(type.boundType) + "}";
aoqi@0 292 default:
aoqi@0 293 throw new AssertionError();
aoqi@0 294 }
aoqi@0 295 }
aoqi@0 296
aoqi@0 297 };
aoqi@0 298 }
aoqi@0 299
aoqi@0 300
aoqi@0 301 @interface Desc {
aoqi@0 302 String d();
aoqi@0 303 String t();
aoqi@0 304 }
aoqi@0 305
aoqi@0 306 @interface Sig {
aoqi@0 307 String s();
aoqi@0 308 String t();
aoqi@0 309 }
aoqi@0 310
aoqi@0 311 class Clss { }
aoqi@0 312 interface Intf { }
aoqi@0 313 class GenClss<T> { }
aoqi@0 314
aoqi@0 315 class Test {
aoqi@0 316 // fields
aoqi@0 317
aoqi@0 318 @Desc(d="Z", t="S{boolean}")
aoqi@0 319 boolean z;
aoqi@0 320
aoqi@0 321 @Desc(d="B", t="S{byte}")
aoqi@0 322 byte b;
aoqi@0 323
aoqi@0 324 @Desc(d="C", t="S{char}")
aoqi@0 325 char c;
aoqi@0 326
aoqi@0 327 @Desc(d="D", t="S{double}")
aoqi@0 328 double d;
aoqi@0 329
aoqi@0 330 @Desc(d="F", t="S{float}")
aoqi@0 331 float f;
aoqi@0 332
aoqi@0 333 @Desc(d="I", t="S{int}")
aoqi@0 334 int i;
aoqi@0 335
aoqi@0 336 @Desc(d="J", t="S{long}")
aoqi@0 337 long l;
aoqi@0 338
aoqi@0 339 @Desc(d="S", t="S{short}")
aoqi@0 340 short s;
aoqi@0 341
aoqi@0 342 @Desc(d="LClss;", t="C{Clss}")
aoqi@0 343 Clss clss;
aoqi@0 344
aoqi@0 345 @Desc(d="LIntf;", t="C{Intf}")
aoqi@0 346 Intf intf;
aoqi@0 347
aoqi@0 348 @Desc(d="[I", t="A{S{int}}")
aoqi@0 349 int[] ai;
aoqi@0 350
aoqi@0 351 @Desc(d="[LClss;", t="A{C{Clss}}")
aoqi@0 352 Clss[] aClss;
aoqi@0 353
aoqi@0 354 @Desc(d="LGenClss;", t="C{GenClss}")
aoqi@0 355 @Sig(s="LGenClss<LClss;>;", t="C{GenClss<C{Clss}>}")
aoqi@0 356 GenClss<Clss> genClass;
aoqi@0 357
aoqi@0 358 // methods, return types
aoqi@0 359
aoqi@0 360 @Desc(d="()V", t="M{S{void}()}")
aoqi@0 361 void mv0() { }
aoqi@0 362
aoqi@0 363 @Desc(d="()I", t="M{S{int}()}")
aoqi@0 364 int mi0() { return 0; }
aoqi@0 365
aoqi@0 366 @Desc(d="()LClss;", t="M{C{Clss}()}")
aoqi@0 367 Clss mclss0() { return null; }
aoqi@0 368
aoqi@0 369 @Desc(d="()[I", t="M{A{S{int}}()}")
aoqi@0 370 int[] mai0() { return null; }
aoqi@0 371
aoqi@0 372 @Desc(d="()[LClss;", t="M{A{C{Clss}}()}")
aoqi@0 373 Clss[] maClss0() { return null; }
aoqi@0 374
aoqi@0 375 @Desc(d="()LGenClss;", t="M{C{GenClss}()}")
aoqi@0 376 @Sig(s="()LGenClss<LClss;>;", t="M{C{GenClss<C{Clss}>}()}")
aoqi@0 377 GenClss<Clss> mgenClss0() { return null; }
aoqi@0 378
aoqi@0 379 @Desc(d="()LGenClss;", t="M{C{GenClss}()}")
aoqi@0 380 @Sig(s="()LGenClss<*>;", t="M{C{GenClss<W{?}>}()}")
aoqi@0 381 GenClss<?> mgenClssW0() { return null; }
aoqi@0 382
aoqi@0 383 @Desc(d="()LGenClss;", t="M{C{GenClss}()}")
aoqi@0 384 @Sig(s="()LGenClss<+LClss;>;", t="M{C{GenClss<W{e,C{Clss}}>}()}")
aoqi@0 385 GenClss<? extends Clss> mgenClssWExtClss0() { return null; }
aoqi@0 386
aoqi@0 387 @Desc(d="()LGenClss;", t="M{C{GenClss}()}")
aoqi@0 388 @Sig(s="()LGenClss<-LClss;>;", t="M{C{GenClss<W{s,C{Clss}}>}()}")
aoqi@0 389 GenClss<? super Clss> mgenClssWSupClss0() { return null; }
aoqi@0 390
aoqi@0 391 @Desc(d="()Ljava/lang/Object;", t="M{C{java/lang/Object}()}")
aoqi@0 392 @Sig(s="<T:Ljava/lang/Object;>()TT;", t="M{<TA{T:cC{java/lang/Object}}>S{T}()}")
aoqi@0 393 <T> T mt0() { return null; }
aoqi@0 394
aoqi@0 395 @Desc(d="()LGenClss;", t="M{C{GenClss}()}")
aoqi@0 396 @Sig(s="<T:Ljava/lang/Object;>()LGenClss<+TT;>;",
aoqi@0 397 t="M{<TA{T:cC{java/lang/Object}}>C{GenClss<W{e,S{T}}>}()}")
aoqi@0 398 <T> GenClss<? extends T> mgenClssWExtT0() { return null; }
aoqi@0 399
aoqi@0 400 @Desc(d="()LGenClss;", t="M{C{GenClss}()}")
aoqi@0 401 @Sig(s="<T:Ljava/lang/Object;>()LGenClss<-TT;>;", t="M{<TA{T:cC{java/lang/Object}}>C{GenClss<W{s,S{T}}>}()}")
aoqi@0 402 <T> GenClss<? super T> mgenClssWSupT0() { return null; }
aoqi@0 403
aoqi@0 404 // methods, arg types
aoqi@0 405
aoqi@0 406 @Desc(d="(I)V", t="M{S{void}(S{int})}")
aoqi@0 407 void mi1(int arg) { }
aoqi@0 408
aoqi@0 409 @Desc(d="(LClss;)V", t="M{S{void}(C{Clss})}")
aoqi@0 410 void mclss1(Clss arg) { }
aoqi@0 411
aoqi@0 412 @Desc(d="([I)V", t="M{S{void}(A{S{int}})}")
aoqi@0 413 void mai1(int[] arg) { }
aoqi@0 414
aoqi@0 415 @Desc(d="([LClss;)V", t="M{S{void}(A{C{Clss}})}")
aoqi@0 416 void maClss1(Clss[] arg) { }
aoqi@0 417
aoqi@0 418 @Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
aoqi@0 419 @Sig(s="(LGenClss<LClss;>;)V", t="M{S{void}(C{GenClss<C{Clss}>})}")
aoqi@0 420 void mgenClss1(GenClss<Clss> arg) { }
aoqi@0 421
aoqi@0 422 @Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
aoqi@0 423 @Sig(s="(LGenClss<*>;)V", t="M{S{void}(C{GenClss<W{?}>})}")
aoqi@0 424 void mgenClssW1(GenClss<?> arg) { }
aoqi@0 425
aoqi@0 426 @Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
aoqi@0 427 @Sig(s="(LGenClss<+LClss;>;)V", t="M{S{void}(C{GenClss<W{e,C{Clss}}>})}")
aoqi@0 428 void mgenClssWExtClss1(GenClss<? extends Clss> arg) { }
aoqi@0 429
aoqi@0 430 @Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
aoqi@0 431 @Sig(s="(LGenClss<-LClss;>;)V", t="M{S{void}(C{GenClss<W{s,C{Clss}}>})}")
aoqi@0 432 void mgenClssWSupClss1(GenClss<? super Clss> arg) { }
aoqi@0 433
aoqi@0 434 @Desc(d="(Ljava/lang/Object;)V", t="M{S{void}(C{java/lang/Object})}")
aoqi@0 435 @Sig(s="<T:Ljava/lang/Object;>(TT;)V",
aoqi@0 436 t="M{<TA{T:cC{java/lang/Object}}>S{void}(S{T})}")
aoqi@0 437 <T> void mt1(T arg) { }
aoqi@0 438
aoqi@0 439 @Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
aoqi@0 440 @Sig(s="<T:Ljava/lang/Object;>(LGenClss<+TT;>;)V",
aoqi@0 441 t="M{<TA{T:cC{java/lang/Object}}>S{void}(C{GenClss<W{e,S{T}}>})}")
aoqi@0 442 <T> void mgenClssWExtT1(GenClss<? extends T> arg) { }
aoqi@0 443
aoqi@0 444 @Desc(d="(LGenClss;)V", t="M{S{void}(C{GenClss})}")
aoqi@0 445 @Sig(s="<T:Ljava/lang/Object;>(LGenClss<-TT;>;)V",
aoqi@0 446 t="M{<TA{T:cC{java/lang/Object}}>S{void}(C{GenClss<W{s,S{T}}>})}")
aoqi@0 447 <T> void mgenClssWSupT1(GenClss<? super T> arg) { }
aoqi@0 448
aoqi@0 449 // methods, throws
aoqi@0 450
aoqi@0 451 @Desc(d="()V", t="M{S{void}()}")
aoqi@0 452 void m_E() throws Exception { }
aoqi@0 453
aoqi@0 454 @Desc(d="()V", t="M{S{void}()}")
aoqi@0 455 @Sig(s="<T:Ljava/lang/Throwable;>()V^TT;",
aoqi@0 456 t="M{<TA{T:cC{java/lang/Throwable}}>S{void}()S{T}}")
aoqi@0 457 <T extends Throwable> void m_T() throws T { }
aoqi@0 458
aoqi@0 459 // inner classes
aoqi@0 460
aoqi@0 461 static class X {
aoqi@0 462 // no sig
aoqi@0 463 class P { }
aoqi@0 464
aoqi@0 465 @Sig(s="<TQ:Ljava/lang/Object;>LTest$X$P;",
aoqi@0 466 t="CS{<TA{TQ:cC{java/lang/Object}}>C{Test$X$P}}")
aoqi@0 467 class Q<TQ> extends P { }
aoqi@0 468
aoqi@0 469 @Sig(s="<TR:Ljava/lang/Object;>LTest$X$Q<TTR;>;",
aoqi@0 470 t="CS{<TA{TR:cC{java/lang/Object}}>C{Test$X$Q<S{TR}>}}")
aoqi@0 471 class R<TR> extends Q<TR> { }
aoqi@0 472 }
aoqi@0 473
aoqi@0 474 @Sig(s="<TY:Ljava/lang/Object;>Ljava/lang/Object;",
aoqi@0 475 t="CS{<TA{TY:cC{java/lang/Object}}>C{java/lang/Object}}")
aoqi@0 476 static class Y<TY> {
aoqi@0 477 // no sig
aoqi@0 478 class P { }
aoqi@0 479
aoqi@0 480 @Sig(s="<TQ:Ljava/lang/Object;>LTest$Y<TTY;>.P;",
aoqi@0 481 t="CS{<TA{TQ:cC{java/lang/Object}}>C{C{Test$Y<S{TY}>}.P}}")
aoqi@0 482 class Q<TQ> extends P { }
aoqi@0 483
aoqi@0 484 @Sig(s="<TR:Ljava/lang/Object;>LTest$Y<TTY;>.Q<TTR;>;",
aoqi@0 485 t="CS{<TA{TR:cC{java/lang/Object}}>C{C{Test$Y<S{TY}>}.Q<S{TR}>}}")
aoqi@0 486 class R<TR> extends Q<TR> {
aoqi@0 487 // no sig
aoqi@0 488 class R1 { }
aoqi@0 489
aoqi@0 490 @Sig(s="<TR2:Ljava/lang/Object;>LTest$Y<TTY;>.R<TTR;>.R1;",
aoqi@0 491 t="CS{<TA{TR2:cC{java/lang/Object}}>C{C{C{Test$Y<S{TY}>}.R<S{TR}>}.R1}}")
aoqi@0 492 class R2<TR2> extends R1 { }
aoqi@0 493 }
aoqi@0 494
aoqi@0 495 @Sig(s="LTest$Y<TTY;>.Q<TTY;>;", t="C{C{Test$Y<S{TY}>}.Q<S{TY}>}")
aoqi@0 496 class S extends Q<TY> {
aoqi@0 497 // no sig
aoqi@0 498 class S1 { }
aoqi@0 499
aoqi@0 500 @Sig(s="<TS2:Ljava/lang/Object;>LTest$Y<TTY;>.S.S1;",
aoqi@0 501 t="CS{<TA{TS2:cC{java/lang/Object}}>C{C{C{Test$Y<S{TY}>}.S}.S1}}")
aoqi@0 502 class S2<TS2> extends S1 { }
aoqi@0 503
aoqi@0 504 @Sig(s="LTest$Y<TTY;>.S.S2<TTY;>;",
aoqi@0 505 t="C{C{C{Test$Y<S{TY}>}.S}.S2<S{TY}>}")
aoqi@0 506 class S3 extends S2<TY> { }
aoqi@0 507 }
aoqi@0 508 }
aoqi@0 509 }
aoqi@0 510
aoqi@0 511

mercurial