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