69 return e.toString(); 70 } 71 } 72 73 public final ConstantPool constant_pool; 74 public final Position position; 75 public final Annotation annotation; 76 77 private static Position read_position(ClassReader cr) throws IOException, Annotation.InvalidAnnotation { 78 // Copied from ClassReader 79 int tag = cr.readUnsignedByte(); // TargetType tag is a byte 80 if (!TargetType.isValidTargetTypeValue(tag)) 81 throw new Annotation.InvalidAnnotation("TypeAnnotation: Invalid type annotation target type value: " + String.format("0x%02X", tag)); 82 83 TargetType type = TargetType.fromTargetTypeValue(tag); 84 85 Position position = new Position(); 86 position.type = type; 87 88 switch (type) { 89 // type cast 90 case CAST: 91 // instanceof 92 case INSTANCEOF: 93 // new expression 94 case NEW: 95 position.offset = cr.readUnsignedShort(); 96 break; 97 // local variable 98 case LOCAL_VARIABLE: 99 // resource variable 100 case RESOURCE_VARIABLE: 101 int table_length = cr.readUnsignedShort(); 102 position.lvarOffset = new int[table_length]; 103 position.lvarLength = new int[table_length]; 104 position.lvarIndex = new int[table_length]; 105 for (int i = 0; i < table_length; ++i) { 106 position.lvarOffset[i] = cr.readUnsignedShort(); 107 position.lvarLength[i] = cr.readUnsignedShort(); 108 position.lvarIndex[i] = cr.readUnsignedShort(); 109 } 110 break; 111 // exception parameter 112 case EXCEPTION_PARAMETER: 113 position.exception_index = cr.readUnsignedByte(); 114 break; 125 case CLASS_TYPE_PARAMETER_BOUND: 126 case METHOD_TYPE_PARAMETER_BOUND: 127 position.parameter_index = cr.readUnsignedByte(); 128 position.bound_index = cr.readUnsignedByte(); 129 break; 130 // class extends or implements clause 131 case CLASS_EXTENDS: 132 int in = cr.readUnsignedShort(); 133 if (in == 0xFFFF) 134 in = -1; 135 position.type_index = in; 136 break; 137 // throws 138 case THROWS: 139 position.type_index = cr.readUnsignedShort(); 140 break; 141 // method parameter 142 case METHOD_FORMAL_PARAMETER: 143 position.parameter_index = cr.readUnsignedByte(); 144 break; 145 // method/constructor/reference type argument 146 case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: 147 case METHOD_INVOCATION_TYPE_ARGUMENT: 148 case METHOD_REFERENCE_TYPE_ARGUMENT: 149 position.offset = cr.readUnsignedShort(); 150 position.type_index = cr.readUnsignedByte(); 151 break; 152 // We don't need to worry about these 153 case METHOD_RETURN: 154 case FIELD: 155 break; 156 // lambda formal parameter 157 case LAMBDA_FORMAL_PARAMETER: 158 position.parameter_index = cr.readUnsignedByte(); 159 break; 160 case UNKNOWN: 161 throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!"); 162 default: 163 throw new AssertionError("TypeAnnotation: Unknown target type: " + type); 164 } 165 166 { // Write type path 167 int len = cr.readUnsignedByte(); 168 List<Integer> loc = new ArrayList<Integer>(len); 169 for (int i = 0; i < len * TypePathEntry.bytesPerEntry; ++i) 170 loc.add(cr.readUnsignedByte()); 171 position.location = Position.getTypePathFromBinary(loc); 172 } 173 return position; 174 } 175 176 private static int position_length(Position pos) { 177 int n = 0; 178 n += 1; // TargetType tag is a byte 179 switch (pos.type) { 180 // type cast 181 case CAST: 182 // instanceof 183 case INSTANCEOF: 184 // new expression 185 case NEW: 186 n += 2; 187 break; 188 // local variable 189 case LOCAL_VARIABLE: 190 // resource variable 191 case RESOURCE_VARIABLE: 192 n += 2; // table_length; 193 int table_length = pos.lvarOffset.length; 194 n += 2 * table_length; // offset 195 n += 2 * table_length; // length; 196 n += 2 * table_length; // index 197 break; 198 // exception parameter 199 case EXCEPTION_PARAMETER: 200 n += 1; // exception_index 201 break; 202 // method receiver 203 case METHOD_RECEIVER: 204 // Do nothing 205 break; 206 // type parameter 207 case CLASS_TYPE_PARAMETER: 208 case METHOD_TYPE_PARAMETER: 209 n += 1; // parameter_index; 210 break; 211 // type parameter bound 212 case CLASS_TYPE_PARAMETER_BOUND: 213 case METHOD_TYPE_PARAMETER_BOUND: 214 n += 1; // parameter_index 215 n += 1; // bound_index 216 break; 217 // class extends or implements clause 218 case CLASS_EXTENDS: 219 n += 2; // type_index 220 break; 221 // throws 222 case THROWS: 223 n += 2; // type_index 224 break; 225 // method parameter 226 case METHOD_FORMAL_PARAMETER: 227 n += 1; // parameter_index 228 break; 229 // method/constructor/reference type argument 230 case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: 231 case METHOD_INVOCATION_TYPE_ARGUMENT: 232 case METHOD_REFERENCE_TYPE_ARGUMENT: 233 n += 2; // offset 234 n += 1; // type index 235 break; 236 // We don't need to worry about these 237 case METHOD_RETURN: 238 case FIELD: 239 break; 240 // lambda formal parameter 241 case LAMBDA_FORMAL_PARAMETER: 242 n += 1; // parameter_index 243 break; 244 case UNKNOWN: 245 throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!"); 246 default: 247 throw new AssertionError("TypeAnnotation: Unknown target type: " + pos.type); 248 } 249 250 { 251 n += 1; // length 252 n += TypePathEntry.bytesPerEntry * pos.location.size(); // bytes for actual array 253 } 254 255 return n; 256 } 257 258 // Code duplicated from com.sun.tools.javac.code.TypeAnnotationPosition 259 public static class Position { 260 public enum TypePathEntryKind { 261 ARRAY(0), 262 INNER_TYPE(1), 263 WILDCARD(2), 360 public int bound_index = Integer.MIN_VALUE; 361 362 // For type parameter and method parameter 363 public int parameter_index = Integer.MIN_VALUE; 364 365 // For class extends, implements, and throws clauses 366 public int type_index = Integer.MIN_VALUE; 367 368 // For exception parameters, index into exception table 369 public int exception_index = Integer.MIN_VALUE; 370 371 public Position() {} 372 373 @Override 374 public String toString() { 375 StringBuilder sb = new StringBuilder(); 376 sb.append('['); 377 sb.append(type); 378 379 switch (type) { 380 // type cast 381 case CAST: 382 // instanceof 383 case INSTANCEOF: 384 // new expression 385 case NEW: 386 sb.append(", offset = "); 387 sb.append(offset); 388 break; 389 // local variable 390 case LOCAL_VARIABLE: 391 // resource variable 392 case RESOURCE_VARIABLE: 393 if (lvarOffset == null) { 394 sb.append(", lvarOffset is null!"); 395 break; 396 } 397 sb.append(", {"); 398 for (int i = 0; i < lvarOffset.length; ++i) { 399 if (i != 0) sb.append("; "); 400 sb.append("start_pc = "); 401 sb.append(lvarOffset[i]); 402 sb.append(", length = "); 403 sb.append(lvarLength[i]); 404 sb.append(", index = "); 405 sb.append(lvarIndex[i]); 427 // class extends or implements clause 428 case CLASS_EXTENDS: 429 sb.append(", type_index = "); 430 sb.append(type_index); 431 break; 432 // throws 433 case THROWS: 434 sb.append(", type_index = "); 435 sb.append(type_index); 436 break; 437 // exception parameter 438 case EXCEPTION_PARAMETER: 439 sb.append(", exception_index = "); 440 sb.append(exception_index); 441 break; 442 // method parameter 443 case METHOD_FORMAL_PARAMETER: 444 sb.append(", param_index = "); 445 sb.append(parameter_index); 446 break; 447 // method/constructor/reference type argument 448 case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: 449 case METHOD_INVOCATION_TYPE_ARGUMENT: 450 case METHOD_REFERENCE_TYPE_ARGUMENT: 451 sb.append(", offset = "); 452 sb.append(offset); 453 sb.append(", type_index = "); 454 sb.append(type_index); 455 break; 456 // We don't need to worry about these 457 case METHOD_RETURN: 458 case FIELD: 459 break; 460 // lambda formal parameter 461 case LAMBDA_FORMAL_PARAMETER: 462 // TODO: also needs an offset? 463 sb.append(", param_index = "); 464 sb.append(parameter_index); 465 break; 466 case UNKNOWN: 467 sb.append(", position UNKNOWN!"); 468 break; 469 default: 470 throw new AssertionError("Unknown target type: " + type); 471 } 472 473 // Append location data for generics/arrays. 474 if (!location.isEmpty()) { 475 sb.append(", location = ("); 476 sb.append(location); 477 sb.append(")"); 478 } 479 480 sb.append(", pos = "); 481 sb.append(pos); 482 483 sb.append(']'); 484 return sb.toString(); 485 } 547 METHOD_RETURN(0x14), 548 549 /** For annotations on the method receiver. */ 550 METHOD_RECEIVER(0x15), 551 552 /** For annotations on a method parameter. */ 553 METHOD_FORMAL_PARAMETER(0x16), 554 555 /** For annotations on a throws clause in a method declaration. */ 556 THROWS(0x17), 557 558 /** For annotations on a local variable. */ 559 LOCAL_VARIABLE(0x40, true), 560 561 /** For annotations on a resource variable. */ 562 RESOURCE_VARIABLE(0x41, true), 563 564 /** For annotations on an exception parameter. */ 565 EXCEPTION_PARAMETER(0x42, true), 566 567 /** For annotations on a typecast. */ 568 CAST(0x43, true), 569 570 /** For annotations on a type test. */ 571 INSTANCEOF(0x44, true), 572 573 /** For annotations on an object creation expression. */ 574 NEW(0x45, true), 575 576 /** For annotations on a type argument of an object creation expression. */ 577 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x46, true), 578 579 /** For annotations on a type argument of a method call. */ 580 METHOD_INVOCATION_TYPE_ARGUMENT(0x47, true), 581 582 /** For annotations on a lambda parameter type. */ 583 LAMBDA_FORMAL_PARAMETER(0x48, true), 584 585 /** For annotations on a method reference. */ 586 METHOD_REFERENCE(0x49, true), 587 588 /** For annotations on a type argument of a method reference. */ 589 METHOD_REFERENCE_TYPE_ARGUMENT(0x50, true), 590 591 /** For annotations with an unknown target. */ 592 UNKNOWN(0xFF); 593 594 private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x50; 595 596 private final int targetTypeValue; 597 private final boolean isLocal; 598 599 private TargetType(int targetTypeValue) { 600 this(targetTypeValue, false); 601 } 602 603 private TargetType(int targetTypeValue, boolean isLocal) { 604 if (targetTypeValue < 0 605 || targetTypeValue > 255) 606 throw new AssertionError("Attribute type value needs to be an unsigned byte: " + String.format("0x%02X", targetTypeValue)); 607 this.targetTypeValue = targetTypeValue; 608 this.isLocal = isLocal; 609 } 610 611 /** 612 * Returns whether or not this TargetType represents an annotation whose 613 * target is exclusively a tree in a method body 614 * | 69 return e.toString(); 70 } 71 } 72 73 public final ConstantPool constant_pool; 74 public final Position position; 75 public final Annotation annotation; 76 77 private static Position read_position(ClassReader cr) throws IOException, Annotation.InvalidAnnotation { 78 // Copied from ClassReader 79 int tag = cr.readUnsignedByte(); // TargetType tag is a byte 80 if (!TargetType.isValidTargetTypeValue(tag)) 81 throw new Annotation.InvalidAnnotation("TypeAnnotation: Invalid type annotation target type value: " + String.format("0x%02X", tag)); 82 83 TargetType type = TargetType.fromTargetTypeValue(tag); 84 85 Position position = new Position(); 86 position.type = type; 87 88 switch (type) { 89 // instanceof 90 case INSTANCEOF: 91 // new expression 92 case NEW: 93 // constructor/method reference receiver 94 case CONSTRUCTOR_REFERENCE: 95 case METHOD_REFERENCE: 96 position.offset = cr.readUnsignedShort(); 97 break; 98 // local variable 99 case LOCAL_VARIABLE: 100 // resource variable 101 case RESOURCE_VARIABLE: 102 int table_length = cr.readUnsignedShort(); 103 position.lvarOffset = new int[table_length]; 104 position.lvarLength = new int[table_length]; 105 position.lvarIndex = new int[table_length]; 106 for (int i = 0; i < table_length; ++i) { 107 position.lvarOffset[i] = cr.readUnsignedShort(); 108 position.lvarLength[i] = cr.readUnsignedShort(); 109 position.lvarIndex[i] = cr.readUnsignedShort(); 110 } 111 break; 112 // exception parameter 113 case EXCEPTION_PARAMETER: 114 position.exception_index = cr.readUnsignedByte(); 115 break; 126 case CLASS_TYPE_PARAMETER_BOUND: 127 case METHOD_TYPE_PARAMETER_BOUND: 128 position.parameter_index = cr.readUnsignedByte(); 129 position.bound_index = cr.readUnsignedByte(); 130 break; 131 // class extends or implements clause 132 case CLASS_EXTENDS: 133 int in = cr.readUnsignedShort(); 134 if (in == 0xFFFF) 135 in = -1; 136 position.type_index = in; 137 break; 138 // throws 139 case THROWS: 140 position.type_index = cr.readUnsignedShort(); 141 break; 142 // method parameter 143 case METHOD_FORMAL_PARAMETER: 144 position.parameter_index = cr.readUnsignedByte(); 145 break; 146 // type cast 147 case CAST: 148 // method/constructor/reference type argument 149 case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: 150 case METHOD_INVOCATION_TYPE_ARGUMENT: 151 case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: 152 case METHOD_REFERENCE_TYPE_ARGUMENT: 153 position.offset = cr.readUnsignedShort(); 154 position.type_index = cr.readUnsignedByte(); 155 break; 156 // We don't need to worry about these 157 case METHOD_RETURN: 158 case FIELD: 159 break; 160 case UNKNOWN: 161 throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!"); 162 default: 163 throw new AssertionError("TypeAnnotation: Unknown target type: " + type); 164 } 165 166 { // Write type path 167 int len = cr.readUnsignedByte(); 168 List<Integer> loc = new ArrayList<Integer>(len); 169 for (int i = 0; i < len * TypePathEntry.bytesPerEntry; ++i) 170 loc.add(cr.readUnsignedByte()); 171 position.location = Position.getTypePathFromBinary(loc); 172 } 173 return position; 174 } 175 176 private static int position_length(Position pos) { 177 int n = 0; 178 n += 1; // TargetType tag is a byte 179 switch (pos.type) { 180 // instanceof 181 case INSTANCEOF: 182 // new expression 183 case NEW: 184 // constructor/method reference receiver 185 case CONSTRUCTOR_REFERENCE: 186 case METHOD_REFERENCE: 187 n += 2; // offset 188 break; 189 // local variable 190 case LOCAL_VARIABLE: 191 // resource variable 192 case RESOURCE_VARIABLE: 193 n += 2; // table_length; 194 int table_length = pos.lvarOffset.length; 195 n += 2 * table_length; // offset 196 n += 2 * table_length; // length 197 n += 2 * table_length; // index 198 break; 199 // exception parameter 200 case EXCEPTION_PARAMETER: 201 n += 1; // exception_index 202 break; 203 // method receiver 204 case METHOD_RECEIVER: 205 // Do nothing 206 break; 207 // type parameter 208 case CLASS_TYPE_PARAMETER: 209 case METHOD_TYPE_PARAMETER: 210 n += 1; // parameter_index 211 break; 212 // type parameter bound 213 case CLASS_TYPE_PARAMETER_BOUND: 214 case METHOD_TYPE_PARAMETER_BOUND: 215 n += 1; // parameter_index 216 n += 1; // bound_index 217 break; 218 // class extends or implements clause 219 case CLASS_EXTENDS: 220 n += 2; // type_index 221 break; 222 // throws 223 case THROWS: 224 n += 2; // type_index 225 break; 226 // method parameter 227 case METHOD_FORMAL_PARAMETER: 228 n += 1; // parameter_index 229 break; 230 // type cast 231 case CAST: 232 // method/constructor/reference type argument 233 case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: 234 case METHOD_INVOCATION_TYPE_ARGUMENT: 235 case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: 236 case METHOD_REFERENCE_TYPE_ARGUMENT: 237 n += 2; // offset 238 n += 1; // type index 239 break; 240 // We don't need to worry about these 241 case METHOD_RETURN: 242 case FIELD: 243 break; 244 case UNKNOWN: 245 throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!"); 246 default: 247 throw new AssertionError("TypeAnnotation: Unknown target type: " + pos.type); 248 } 249 250 { 251 n += 1; // length 252 n += TypePathEntry.bytesPerEntry * pos.location.size(); // bytes for actual array 253 } 254 255 return n; 256 } 257 258 // Code duplicated from com.sun.tools.javac.code.TypeAnnotationPosition 259 public static class Position { 260 public enum TypePathEntryKind { 261 ARRAY(0), 262 INNER_TYPE(1), 263 WILDCARD(2), 360 public int bound_index = Integer.MIN_VALUE; 361 362 // For type parameter and method parameter 363 public int parameter_index = Integer.MIN_VALUE; 364 365 // For class extends, implements, and throws clauses 366 public int type_index = Integer.MIN_VALUE; 367 368 // For exception parameters, index into exception table 369 public int exception_index = Integer.MIN_VALUE; 370 371 public Position() {} 372 373 @Override 374 public String toString() { 375 StringBuilder sb = new StringBuilder(); 376 sb.append('['); 377 sb.append(type); 378 379 switch (type) { 380 // instanceof 381 case INSTANCEOF: 382 // new expression 383 case NEW: 384 // constructor/method reference receiver 385 case CONSTRUCTOR_REFERENCE: 386 case METHOD_REFERENCE: 387 sb.append(", offset = "); 388 sb.append(offset); 389 break; 390 // local variable 391 case LOCAL_VARIABLE: 392 // resource variable 393 case RESOURCE_VARIABLE: 394 if (lvarOffset == null) { 395 sb.append(", lvarOffset is null!"); 396 break; 397 } 398 sb.append(", {"); 399 for (int i = 0; i < lvarOffset.length; ++i) { 400 if (i != 0) sb.append("; "); 401 sb.append("start_pc = "); 402 sb.append(lvarOffset[i]); 403 sb.append(", length = "); 404 sb.append(lvarLength[i]); 405 sb.append(", index = "); 406 sb.append(lvarIndex[i]); 428 // class extends or implements clause 429 case CLASS_EXTENDS: 430 sb.append(", type_index = "); 431 sb.append(type_index); 432 break; 433 // throws 434 case THROWS: 435 sb.append(", type_index = "); 436 sb.append(type_index); 437 break; 438 // exception parameter 439 case EXCEPTION_PARAMETER: 440 sb.append(", exception_index = "); 441 sb.append(exception_index); 442 break; 443 // method parameter 444 case METHOD_FORMAL_PARAMETER: 445 sb.append(", param_index = "); 446 sb.append(parameter_index); 447 break; 448 // type cast 449 case CAST: 450 // method/constructor/reference type argument 451 case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: 452 case METHOD_INVOCATION_TYPE_ARGUMENT: 453 case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: 454 case METHOD_REFERENCE_TYPE_ARGUMENT: 455 sb.append(", offset = "); 456 sb.append(offset); 457 sb.append(", type_index = "); 458 sb.append(type_index); 459 break; 460 // We don't need to worry about these 461 case METHOD_RETURN: 462 case FIELD: 463 break; 464 case UNKNOWN: 465 sb.append(", position UNKNOWN!"); 466 break; 467 default: 468 throw new AssertionError("Unknown target type: " + type); 469 } 470 471 // Append location data for generics/arrays. 472 if (!location.isEmpty()) { 473 sb.append(", location = ("); 474 sb.append(location); 475 sb.append(")"); 476 } 477 478 sb.append(", pos = "); 479 sb.append(pos); 480 481 sb.append(']'); 482 return sb.toString(); 483 } 545 METHOD_RETURN(0x14), 546 547 /** For annotations on the method receiver. */ 548 METHOD_RECEIVER(0x15), 549 550 /** For annotations on a method parameter. */ 551 METHOD_FORMAL_PARAMETER(0x16), 552 553 /** For annotations on a throws clause in a method declaration. */ 554 THROWS(0x17), 555 556 /** For annotations on a local variable. */ 557 LOCAL_VARIABLE(0x40, true), 558 559 /** For annotations on a resource variable. */ 560 RESOURCE_VARIABLE(0x41, true), 561 562 /** For annotations on an exception parameter. */ 563 EXCEPTION_PARAMETER(0x42, true), 564 565 /** For annotations on a type test. */ 566 INSTANCEOF(0x43, true), 567 568 /** For annotations on an object creation expression. */ 569 NEW(0x44, true), 570 571 /** For annotations on a constructor reference receiver. */ 572 CONSTRUCTOR_REFERENCE(0x45, true), 573 574 /** For annotations on a method reference receiver. */ 575 METHOD_REFERENCE(0x46, true), 576 577 /** For annotations on a typecast. */ 578 CAST(0x47, true), 579 580 /** For annotations on a type argument of an object creation expression. */ 581 CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x48, true), 582 583 /** For annotations on a type argument of a method call. */ 584 METHOD_INVOCATION_TYPE_ARGUMENT(0x49, true), 585 586 /** For annotations on a type argument of a constructor reference. */ 587 CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT(0x4A, true), 588 589 /** For annotations on a type argument of a method reference. */ 590 METHOD_REFERENCE_TYPE_ARGUMENT(0x4B, true), 591 592 /** For annotations with an unknown target. */ 593 UNKNOWN(0xFF); 594 595 private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x4B; 596 597 private final int targetTypeValue; 598 private final boolean isLocal; 599 600 private TargetType(int targetTypeValue) { 601 this(targetTypeValue, false); 602 } 603 604 private TargetType(int targetTypeValue, boolean isLocal) { 605 if (targetTypeValue < 0 606 || targetTypeValue > 255) 607 throw new AssertionError("Attribute type value needs to be an unsigned byte: " + String.format("0x%02X", targetTypeValue)); 608 this.targetTypeValue = targetTypeValue; 609 this.isLocal = isLocal; 610 } 611 612 /** 613 * Returns whether or not this TargetType represents an annotation whose 614 * target is exclusively a tree in a method body 615 * |