View Javadoc
1   package mockit.asm.fields;
2   
3   import edu.umd.cs.findbugs.annotations.NonNull;
4   import edu.umd.cs.findbugs.annotations.Nullable;
5   
6   import mockit.asm.BaseWriter;
7   import mockit.asm.SignatureWriter;
8   import mockit.asm.classes.ClassWriter;
9   import mockit.asm.jvmConstants.Opcodes;
10  import mockit.asm.types.JavaType;
11  import mockit.asm.util.ByteVector;
12  
13  import org.checkerframework.checker.index.qual.NonNegative;
14  
15  /**
16   * A visitor to visit a Java field, in the following order: ({@link #visitAnnotation})* {@link #visitEnd}.
17   */
18  public final class FieldVisitor extends BaseWriter {
19      /**
20       * The index of the constant pool item that contains the name of this field.
21       */
22      @NonNegative
23      private final int nameItemIndex;
24  
25      /**
26       * The index of the constant pool item that contains the descriptor of this field.
27       */
28      @NonNegative
29      private final int descItemIndex;
30  
31      @Nullable
32      private final SignatureWriter signatureWriter;
33  
34      /**
35       * The index of the constant pool item that contains the constant value of this field.
36       */
37      @NonNegative
38      private final int valueItemIndex;
39  
40      /**
41       * Initializes a new field visitor.
42       *
43       * @param cw
44       *            the class writer to which this field must be added
45       * @param access
46       *            the field's access flags (see {@link Opcodes})
47       * @param name
48       *            the field's name
49       * @param desc
50       *            the field's descriptor (see {@link JavaType})
51       * @param signature
52       *            the field's signature
53       * @param value
54       *            the field's constant value
55       */
56      public FieldVisitor(@NonNull ClassWriter cw, int access, @NonNull String name, @NonNull String desc,
57              @Nullable String signature, @Nullable Object value) {
58          super(cw.getConstantPoolGeneration(), access);
59  
60          nameItemIndex = cp.newUTF8(name);
61          descItemIndex = cp.newUTF8(desc);
62          signatureWriter = signature == null ? null : new SignatureWriter(cp, signature);
63          valueItemIndex = value == null ? 0 : cp.newConstItem(value).index;
64  
65          createMarkerAttributes(cw.getClassVersion());
66      }
67  
68      /**
69       * Returns the size of this field.
70       */
71      @NonNegative
72      public int getSize() {
73          int size = 8 + getMarkerAttributesSize() + getAnnotationsSize();
74  
75          if (valueItemIndex != 0) {
76              cp.newUTF8("ConstantValue");
77              size += 8;
78          }
79  
80          if (signatureWriter != null) {
81              size += signatureWriter.getSize();
82          }
83  
84          return size;
85      }
86  
87      /**
88       * Puts the content of this field into the given byte vector.
89       */
90      @Override
91      protected void put(@NonNull ByteVector out) {
92          putAccess(out, 0);
93          out.putShort(nameItemIndex);
94          out.putShort(descItemIndex);
95  
96          int attributeCount = getAttributeCount();
97          out.putShort(attributeCount);
98  
99          if (valueItemIndex != 0) {
100             out.putShort(cp.newUTF8("ConstantValue"));
101             out.putInt(2).putShort(valueItemIndex);
102         }
103 
104         putMarkerAttributes(out);
105 
106         if (signatureWriter != null) {
107             signatureWriter.put(out);
108         }
109 
110         putAnnotations(out);
111     }
112 
113     @NonNegative
114     private int getAttributeCount() {
115         int attributeCount = getMarkerAttributeCount();
116 
117         if (valueItemIndex != 0) {
118             attributeCount++;
119         }
120 
121         if (signatureWriter != null) {
122             attributeCount++;
123         }
124 
125         if (annotations != null) {
126             attributeCount++;
127         }
128 
129         return attributeCount;
130     }
131 }