Reads a JVMS field_info structure and makes the given visitor visit it. @param classVisitor the visitor that must visit the field. @param context information about the class being parsed. @param fieldInfoOffset the start offset of the field_info structure. @return the offset of the first byte follo
(
final ClassVisitor classVisitor, final Context context, final int fieldInfoOffset)
| 822 | * @return the offset of the first byte following the field_info structure. |
| 823 | */ |
| 824 | private int readField( |
| 825 | final ClassVisitor classVisitor, final Context context, final int fieldInfoOffset) { |
| 826 | char[] charBuffer = context.charBuffer; |
| 827 | |
| 828 | // Read the access_flags, name_index and descriptor_index fields. |
| 829 | int currentOffset = fieldInfoOffset; |
| 830 | int accessFlags = readUnsignedShort(currentOffset); |
| 831 | String name = readUTF8(currentOffset + 2, charBuffer); |
| 832 | String descriptor = readUTF8(currentOffset + 4, charBuffer); |
| 833 | currentOffset += 6; |
| 834 | |
| 835 | // Read the field attributes (the variables are ordered as in Section 4.7 of the JVMS). |
| 836 | // Attribute offsets exclude the attribute_name_index and attribute_length fields. |
| 837 | // - The value corresponding to the ConstantValue attribute, or null. |
| 838 | Object constantValue = null; |
| 839 | // - The string corresponding to the Signature attribute, or null. |
| 840 | String signature = null; |
| 841 | // - The offset of the RuntimeVisibleAnnotations attribute, or 0. |
| 842 | int runtimeVisibleAnnotationsOffset = 0; |
| 843 | // - The offset of the RuntimeInvisibleAnnotations attribute, or 0. |
| 844 | int runtimeInvisibleAnnotationsOffset = 0; |
| 845 | // - The offset of the RuntimeVisibleTypeAnnotations attribute, or 0. |
| 846 | int runtimeVisibleTypeAnnotationsOffset = 0; |
| 847 | // - The offset of the RuntimeInvisibleTypeAnnotations attribute, or 0. |
| 848 | int runtimeInvisibleTypeAnnotationsOffset = 0; |
| 849 | // - The non standard attributes (linked with their {@link Attribute#nextAttribute} field). |
| 850 | // This list in the <i>reverse order</i> or their order in the ClassFile structure. |
| 851 | Attribute attributes = null; |
| 852 | |
| 853 | int attributesCount = readUnsignedShort(currentOffset); |
| 854 | currentOffset += 2; |
| 855 | while (attributesCount-- > 0) { |
| 856 | // Read the attribute_info's attribute_name and attribute_length fields. |
| 857 | String attributeName = readUTF8(currentOffset, charBuffer); |
| 858 | int attributeLength = readInt(currentOffset + 2); |
| 859 | currentOffset += 6; |
| 860 | // The tests are sorted in decreasing frequency order (based on frequencies observed on |
| 861 | // typical classes). |
| 862 | if (Constants.CONSTANT_VALUE.equals(attributeName)) { |
| 863 | int constantvalueIndex = readUnsignedShort(currentOffset); |
| 864 | constantValue = constantvalueIndex == 0 ? null : readConst(constantvalueIndex, charBuffer); |
| 865 | } else if (Constants.SIGNATURE.equals(attributeName)) { |
| 866 | signature = readUTF8(currentOffset, charBuffer); |
| 867 | } else if (Constants.DEPRECATED.equals(attributeName)) { |
| 868 | accessFlags |= Opcodes.ACC_DEPRECATED; |
| 869 | } else if (Constants.SYNTHETIC.equals(attributeName)) { |
| 870 | accessFlags |= Opcodes.ACC_SYNTHETIC; |
| 871 | } else if (Constants.RUNTIME_VISIBLE_ANNOTATIONS.equals(attributeName)) { |
| 872 | runtimeVisibleAnnotationsOffset = currentOffset; |
| 873 | } else if (Constants.RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) { |
| 874 | runtimeVisibleTypeAnnotationsOffset = currentOffset; |
| 875 | } else if (Constants.RUNTIME_INVISIBLE_ANNOTATIONS.equals(attributeName)) { |
| 876 | runtimeInvisibleAnnotationsOffset = currentOffset; |
| 877 | } else if (Constants.RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(attributeName)) { |
| 878 | runtimeInvisibleTypeAnnotationsOffset = currentOffset; |
| 879 | } else { |
| 880 | Attribute attribute = |
| 881 | readAttribute( |
no test coverage detected