Parses a Runtime[In]VisibleTypeAnnotations attribute to find the offset of each type_annotation entry it contains, to find the corresponding labels, and to visit the try catch block annotations. @param methodVisitor the method visitor to be used to visit the try catch block annotations. @param cont
(
final MethodVisitor methodVisitor,
final Context context,
final int runtimeTypeAnnotationsOffset,
final boolean visible)
| 2493 | * 'annotations' array field. |
| 2494 | */ |
| 2495 | private int[] readTypeAnnotations( |
| 2496 | final MethodVisitor methodVisitor, |
| 2497 | final Context context, |
| 2498 | final int runtimeTypeAnnotationsOffset, |
| 2499 | final boolean visible) { |
| 2500 | char[] charBuffer = context.charBuffer; |
| 2501 | int currentOffset = runtimeTypeAnnotationsOffset; |
| 2502 | // Read the num_annotations field and create an array to store the type_annotation offsets. |
| 2503 | int[] typeAnnotationsOffsets = new int[readUnsignedShort(currentOffset)]; |
| 2504 | currentOffset += 2; |
| 2505 | // Parse the 'annotations' array field. |
| 2506 | for (int i = 0; i < typeAnnotationsOffsets.length; ++i) { |
| 2507 | typeAnnotationsOffsets[i] = currentOffset; |
| 2508 | // Parse the type_annotation's target_type and the target_info fields. The size of the |
| 2509 | // target_info field depends on the value of target_type. |
| 2510 | int targetType = readInt(currentOffset); |
| 2511 | switch (targetType >>> 24) { |
| 2512 | case TypeReference.LOCAL_VARIABLE: |
| 2513 | case TypeReference.RESOURCE_VARIABLE: |
| 2514 | // A localvar_target has a variable size, which depends on the value of their table_length |
| 2515 | // field. It also references bytecode offsets, for which we need labels. |
| 2516 | int tableLength = readUnsignedShort(currentOffset + 1); |
| 2517 | currentOffset += 3; |
| 2518 | while (tableLength-- > 0) { |
| 2519 | int startPc = readUnsignedShort(currentOffset); |
| 2520 | int length = readUnsignedShort(currentOffset + 2); |
| 2521 | // Skip the index field (2 bytes). |
| 2522 | currentOffset += 6; |
| 2523 | createLabel(startPc, context.currentMethodLabels); |
| 2524 | createLabel(startPc + length, context.currentMethodLabels); |
| 2525 | } |
| 2526 | break; |
| 2527 | case TypeReference.CAST: |
| 2528 | case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: |
| 2529 | case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT: |
| 2530 | case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: |
| 2531 | case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT: |
| 2532 | currentOffset += 4; |
| 2533 | break; |
| 2534 | case TypeReference.CLASS_EXTENDS: |
| 2535 | case TypeReference.CLASS_TYPE_PARAMETER_BOUND: |
| 2536 | case TypeReference.METHOD_TYPE_PARAMETER_BOUND: |
| 2537 | case TypeReference.THROWS: |
| 2538 | case TypeReference.EXCEPTION_PARAMETER: |
| 2539 | case TypeReference.INSTANCEOF: |
| 2540 | case TypeReference.NEW: |
| 2541 | case TypeReference.CONSTRUCTOR_REFERENCE: |
| 2542 | case TypeReference.METHOD_REFERENCE: |
| 2543 | currentOffset += 3; |
| 2544 | break; |
| 2545 | case TypeReference.CLASS_TYPE_PARAMETER: |
| 2546 | case TypeReference.METHOD_TYPE_PARAMETER: |
| 2547 | case TypeReference.METHOD_FORMAL_PARAMETER: |
| 2548 | case TypeReference.FIELD: |
| 2549 | case TypeReference.METHOD_RETURN: |
| 2550 | case TypeReference.METHOD_RECEIVER: |
| 2551 | default: |
| 2552 | // TypeReference type which can't be used in Code attribute, or which is unknown. |
no test coverage detected