1
2
3
4
5
6 package mockit.asm;
7
8 import edu.umd.cs.findbugs.annotations.NonNull;
9 import edu.umd.cs.findbugs.annotations.Nullable;
10
11 import java.util.List;
12
13 import mockit.asm.annotations.AnnotationVisitor;
14 import mockit.asm.constantPool.ConstantPoolGeneration;
15 import mockit.asm.jvmConstants.Access;
16 import mockit.asm.util.ByteVector;
17
18 import org.checkerframework.checker.index.qual.NonNegative;
19
20 public class BaseWriter {
21
22
23
24 protected ConstantPoolGeneration cp;
25
26
27
28
29 protected int classOrMemberAccess;
30
31 @NonNegative
32 private int deprecatedAttributeIndex;
33 @NonNegative
34 private int syntheticAttributeIndex;
35
36
37
38
39 @Nullable
40 protected AnnotationVisitor annotations;
41
42 protected BaseWriter() {
43 }
44
45 protected BaseWriter(@NonNull ConstantPoolGeneration cp, int classOrMemberAccess) {
46 this.cp = cp;
47 this.classOrMemberAccess = classOrMemberAccess;
48 }
49
50
51
52
53
54
55 @NonNull
56 public final ConstantPoolGeneration getConstantPoolGeneration() {
57 return cp;
58 }
59
60
61
62
63
64
65
66
67
68
69 @Nullable
70 public AnnotationVisitor visitAnnotation(@NonNull String desc) {
71 return addAnnotation(desc);
72 }
73
74 @NonNull
75 private AnnotationVisitor addAnnotation(@NonNull String desc) {
76 AnnotationVisitor aw = new AnnotationVisitor(cp, desc);
77 aw.setNext(annotations);
78 annotations = aw;
79 return aw;
80 }
81
82
83
84
85
86 public void visitEnd() {
87 }
88
89 protected final void createMarkerAttributes(int classVersion) {
90 if (Access.isDeprecated(classOrMemberAccess)) {
91 deprecatedAttributeIndex = cp.newUTF8("Deprecated");
92 }
93
94 if (Access.isSynthetic(classOrMemberAccess, classVersion)) {
95 syntheticAttributeIndex = cp.newUTF8("Synthetic");
96 }
97 }
98
99 @NonNegative
100 protected final int getAnnotationsSize() {
101 if (annotations != null) {
102 getConstantPoolItemForRuntimeVisibleAnnotationsAttribute();
103 return 8 + annotations.getSize();
104 }
105
106 return 0;
107 }
108
109 @NonNegative
110 private int getConstantPoolItemForRuntimeVisibleAnnotationsAttribute() {
111 return cp.newUTF8("RuntimeVisibleAnnotations");
112 }
113
114 @NonNegative
115 protected final int getMarkerAttributeCount() {
116 return (deprecatedAttributeIndex == 0 ? 0 : 1) + (syntheticAttributeIndex == 0 ? 0 : 1);
117 }
118
119 @NonNegative
120 protected final int getMarkerAttributesSize() {
121 int attributeCount = getMarkerAttributeCount();
122 return 6 * attributeCount;
123 }
124
125 protected final void putAccess(@NonNull ByteVector out, int baseMask) {
126 int accessFlag = Access.computeFlag(classOrMemberAccess, baseMask);
127 out.putShort(accessFlag);
128 }
129
130 protected final void putMarkerAttributes(@NonNull ByteVector out) {
131 if (deprecatedAttributeIndex > 0) {
132 out.putShort(deprecatedAttributeIndex).putInt(0);
133 }
134
135 if (syntheticAttributeIndex > 0) {
136 out.putShort(syntheticAttributeIndex).putInt(0);
137 }
138 }
139
140 protected final void putAnnotations(@NonNull ByteVector out) {
141 if (annotations != null) {
142 int item = getConstantPoolItemForRuntimeVisibleAnnotationsAttribute();
143 out.putShort(item);
144 annotations.put(out);
145 }
146 }
147
148 protected void put(@NonNull ByteVector out) {
149 }
150
151 protected static void put(@NonNull ByteVector out, @NonNull List<? extends BaseWriter> writers) {
152 out.putShort(writers.size());
153
154 for (BaseWriter writer : writers) {
155 writer.put(out);
156 }
157 }
158 }