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

Wed, 13 Aug 2014 14:50:00 -0700

author
katleman
date
Wed, 13 Aug 2014 14:50:00 -0700
changeset 2549
0b6cc4ea670f
parent 554
9d9f26857129
child 2525
2eb010b6cb22
permissions
-rw-r--r--

Added tag jdk8u40-b01 for changeset bf89a471779d

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

mercurial