xref: /aosp_15_r20/external/javassist/src/main/javassist/bytecode/AnnotationsAttribute.java (revision f1fbf3c2ab775ce834e0af96b7a85bdc7a0eac65)
1*f1fbf3c2SXin Li /*
2*f1fbf3c2SXin Li  * Javassist, a Java-bytecode translator toolkit.
3*f1fbf3c2SXin Li  * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
4*f1fbf3c2SXin Li  *
5*f1fbf3c2SXin Li  * The contents of this file are subject to the Mozilla Public License Version
6*f1fbf3c2SXin Li  * 1.1 (the "License"); you may not use this file except in compliance with
7*f1fbf3c2SXin Li  * the License.  Alternatively, the contents of this file may be used under
8*f1fbf3c2SXin Li  * the terms of the GNU Lesser General Public License Version 2.1 or later,
9*f1fbf3c2SXin Li  * or the Apache License Version 2.0.
10*f1fbf3c2SXin Li  *
11*f1fbf3c2SXin Li  * Software distributed under the License is distributed on an "AS IS" basis,
12*f1fbf3c2SXin Li  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13*f1fbf3c2SXin Li  * for the specific language governing rights and limitations under the
14*f1fbf3c2SXin Li  * License.
15*f1fbf3c2SXin Li  */
16*f1fbf3c2SXin Li 
17*f1fbf3c2SXin Li package javassist.bytecode;
18*f1fbf3c2SXin Li 
19*f1fbf3c2SXin Li import java.io.ByteArrayOutputStream;
20*f1fbf3c2SXin Li import java.io.DataInputStream;
21*f1fbf3c2SXin Li import java.io.IOException;
22*f1fbf3c2SXin Li import java.util.HashMap;
23*f1fbf3c2SXin Li import java.util.Map;
24*f1fbf3c2SXin Li 
25*f1fbf3c2SXin Li import javassist.bytecode.annotation.Annotation;
26*f1fbf3c2SXin Li import javassist.bytecode.annotation.AnnotationMemberValue;
27*f1fbf3c2SXin Li import javassist.bytecode.annotation.AnnotationsWriter;
28*f1fbf3c2SXin Li import javassist.bytecode.annotation.ArrayMemberValue;
29*f1fbf3c2SXin Li import javassist.bytecode.annotation.BooleanMemberValue;
30*f1fbf3c2SXin Li import javassist.bytecode.annotation.ByteMemberValue;
31*f1fbf3c2SXin Li import javassist.bytecode.annotation.CharMemberValue;
32*f1fbf3c2SXin Li import javassist.bytecode.annotation.ClassMemberValue;
33*f1fbf3c2SXin Li import javassist.bytecode.annotation.DoubleMemberValue;
34*f1fbf3c2SXin Li import javassist.bytecode.annotation.EnumMemberValue;
35*f1fbf3c2SXin Li import javassist.bytecode.annotation.FloatMemberValue;
36*f1fbf3c2SXin Li import javassist.bytecode.annotation.IntegerMemberValue;
37*f1fbf3c2SXin Li import javassist.bytecode.annotation.LongMemberValue;
38*f1fbf3c2SXin Li import javassist.bytecode.annotation.MemberValue;
39*f1fbf3c2SXin Li import javassist.bytecode.annotation.ShortMemberValue;
40*f1fbf3c2SXin Li import javassist.bytecode.annotation.StringMemberValue;
41*f1fbf3c2SXin Li 
42*f1fbf3c2SXin Li /**
43*f1fbf3c2SXin Li  * A class representing
44*f1fbf3c2SXin Li  * <code>RuntimeVisibleAnnotations_attribute</code> and
45*f1fbf3c2SXin Li  * <code>RuntimeInvisibleAnnotations_attribute</code>.
46*f1fbf3c2SXin Li  *
47*f1fbf3c2SXin Li  * <p>To obtain an AnnotationAttribute object, invoke
48*f1fbf3c2SXin Li  * <code>getAttribute(AnnotationsAttribute.visibleTag)</code>
49*f1fbf3c2SXin Li  * in <code>ClassFile</code>, <code>MethodInfo</code>,
50*f1fbf3c2SXin Li  * or <code>FieldInfo</code>.  The obtained attribute is a
51*f1fbf3c2SXin Li  * runtime visible annotations attribute.
52*f1fbf3c2SXin Li  * If the parameter is
53*f1fbf3c2SXin Li  * <code>AnnotationAttribute.invisibleTag</code>, then the obtained
54*f1fbf3c2SXin Li  * attribute is a runtime invisible one.
55*f1fbf3c2SXin Li  *
56*f1fbf3c2SXin Li  * <p>For example,
57*f1fbf3c2SXin Li  *
58*f1fbf3c2SXin Li  * <pre>
59*f1fbf3c2SXin Li  * import javassist.bytecode.annotation.Annotation;
60*f1fbf3c2SXin Li  *    :
61*f1fbf3c2SXin Li  * CtMethod m = ... ;
62*f1fbf3c2SXin Li  * MethodInfo minfo = m.getMethodInfo();
63*f1fbf3c2SXin Li  * AnnotationsAttribute attr = (AnnotationsAttribute)
64*f1fbf3c2SXin Li  *         minfo.getAttribute(AnnotationsAttribute.invisibleTag);
65*f1fbf3c2SXin Li  * Annotation an = attr.getAnnotation("Author");
66*f1fbf3c2SXin Li  * String s = ((StringMemberValue)an.getMemberValue("name")).getValue();
67*f1fbf3c2SXin Li  * System.out.println("@Author(name=" + s + ")");
68*f1fbf3c2SXin Li  * </pre>
69*f1fbf3c2SXin Li  *
70*f1fbf3c2SXin Li  * <p>This code snippet retrieves an annotation of the type <code>Author</code>
71*f1fbf3c2SXin Li  * from the <code>MethodInfo</code> object specified by <code>minfo</code>.
72*f1fbf3c2SXin Li  * Then, it prints the value of <code>name</code> in <code>Author</code>.
73*f1fbf3c2SXin Li  *
74*f1fbf3c2SXin Li  * <p>If the annotation type <code>Author</code> is annotated by a meta annotation:
75*f1fbf3c2SXin Li  *
76*f1fbf3c2SXin Li  * <pre>
77*f1fbf3c2SXin Li  * &#64;Retention(RetentionPolicy.RUNTIME)
78*f1fbf3c2SXin Li  * </pre>
79*f1fbf3c2SXin Li  *
80*f1fbf3c2SXin Li  * <p>Then <code>Author</code> is visible at runtime.  Therefore, the third
81*f1fbf3c2SXin Li  * statement of the code snippet above must be changed into:
82*f1fbf3c2SXin Li  *
83*f1fbf3c2SXin Li  * <pre>
84*f1fbf3c2SXin Li  * AnnotationsAttribute attr = (AnnotationsAttribute)
85*f1fbf3c2SXin Li  *         minfo.getAttribute(AnnotationsAttribute.visibleTag);
86*f1fbf3c2SXin Li  * </pre>
87*f1fbf3c2SXin Li  *
88*f1fbf3c2SXin Li  * <p>The attribute tag must be <code>visibleTag</code> instead of
89*f1fbf3c2SXin Li  * <code>invisibleTag</code>.
90*f1fbf3c2SXin Li  *
91*f1fbf3c2SXin Li  * <p>If the member value of an annotation is not specified, the default value
92*f1fbf3c2SXin Li  * is used as that member value.  If so, <code>getMemberValue()</code> in
93*f1fbf3c2SXin Li  * <code>Annotation</code> returns <code>null</code>
94*f1fbf3c2SXin Li  * since the default value is not included in the
95*f1fbf3c2SXin Li  * <code>AnnotationsAttribute</code>.  It is included in the
96*f1fbf3c2SXin Li  * <code>AnnotationDefaultAttribute</code> of the method declared in the
97*f1fbf3c2SXin Li  * annotation type.
98*f1fbf3c2SXin Li  *
99*f1fbf3c2SXin Li  * <p>If you want to record a new AnnotationAttribute object, execute the
100*f1fbf3c2SXin Li  * following snippet:
101*f1fbf3c2SXin Li  *
102*f1fbf3c2SXin Li  * <pre>
103*f1fbf3c2SXin Li  * ClassFile cf = ... ;
104*f1fbf3c2SXin Li  * ConstPool cp = cf.getConstPool();
105*f1fbf3c2SXin Li  * AnnotationsAttribute attr
106*f1fbf3c2SXin Li  *     = new AnnotationsAttribute(cp, AnnotationsAttribute.visibleTag);
107*f1fbf3c2SXin Li  * Annotation a = new Annotation("Author", cp);
108*f1fbf3c2SXin Li  * a.addMemberValue("name", new StringMemberValue("Chiba", cp));
109*f1fbf3c2SXin Li  * attr.setAnnotation(a);
110*f1fbf3c2SXin Li  * cf.addAttribute(attr);
111*f1fbf3c2SXin Li  * cf.setVersionToJava5();
112*f1fbf3c2SXin Li  * </pre>
113*f1fbf3c2SXin Li  *
114*f1fbf3c2SXin Li  * <p>The last statement is necessary if the class file was produced by
115*f1fbf3c2SXin Li  * <code>javac</code> of JDK 1.4 or earlier.  Otherwise, it is not necessary.
116*f1fbf3c2SXin Li  *
117*f1fbf3c2SXin Li  * @see AnnotationDefaultAttribute
118*f1fbf3c2SXin Li  * @see javassist.bytecode.annotation.Annotation
119*f1fbf3c2SXin Li  */
120*f1fbf3c2SXin Li public class AnnotationsAttribute extends AttributeInfo {
121*f1fbf3c2SXin Li     /**
122*f1fbf3c2SXin Li      * The name of the <code>RuntimeVisibleAnnotations</code> attribute.
123*f1fbf3c2SXin Li      */
124*f1fbf3c2SXin Li     public static final String visibleTag = "RuntimeVisibleAnnotations";
125*f1fbf3c2SXin Li 
126*f1fbf3c2SXin Li     /**
127*f1fbf3c2SXin Li      * The name of the <code>RuntimeInvisibleAnnotations</code> attribute.
128*f1fbf3c2SXin Li      */
129*f1fbf3c2SXin Li     public static final String invisibleTag = "RuntimeInvisibleAnnotations";
130*f1fbf3c2SXin Li 
131*f1fbf3c2SXin Li     /**
132*f1fbf3c2SXin Li      * Constructs a <code>Runtime(In)VisibleAnnotations_attribute</code>.
133*f1fbf3c2SXin Li      *
134*f1fbf3c2SXin Li      * @param cp            constant pool
135*f1fbf3c2SXin Li      * @param attrname      attribute name (<code>visibleTag</code> or
136*f1fbf3c2SXin Li      *                      <code>invisibleTag</code>).
137*f1fbf3c2SXin Li      * @param info          the contents of this attribute.  It does not
138*f1fbf3c2SXin Li      *                      include <code>attribute_name_index</code> or
139*f1fbf3c2SXin Li      *                      <code>attribute_length</code>.
140*f1fbf3c2SXin Li      */
AnnotationsAttribute(ConstPool cp, String attrname, byte[] info)141*f1fbf3c2SXin Li     public AnnotationsAttribute(ConstPool cp, String attrname, byte[] info) {
142*f1fbf3c2SXin Li         super(cp, attrname, info);
143*f1fbf3c2SXin Li     }
144*f1fbf3c2SXin Li 
145*f1fbf3c2SXin Li     /**
146*f1fbf3c2SXin Li      * Constructs an empty
147*f1fbf3c2SXin Li      * <code>Runtime(In)VisibleAnnotations_attribute</code>.
148*f1fbf3c2SXin Li      * A new annotation can be later added to the created attribute
149*f1fbf3c2SXin Li      * by <code>setAnnotations()</code>.
150*f1fbf3c2SXin Li      *
151*f1fbf3c2SXin Li      * @param cp            constant pool
152*f1fbf3c2SXin Li      * @param attrname      attribute name (<code>visibleTag</code> or
153*f1fbf3c2SXin Li      *                      <code>invisibleTag</code>).
154*f1fbf3c2SXin Li      * @see #setAnnotations(Annotation[])
155*f1fbf3c2SXin Li      */
AnnotationsAttribute(ConstPool cp, String attrname)156*f1fbf3c2SXin Li     public AnnotationsAttribute(ConstPool cp, String attrname) {
157*f1fbf3c2SXin Li         this(cp, attrname, new byte[] { 0, 0 });
158*f1fbf3c2SXin Li     }
159*f1fbf3c2SXin Li 
160*f1fbf3c2SXin Li     /**
161*f1fbf3c2SXin Li      * @param n     the attribute name.
162*f1fbf3c2SXin Li      */
AnnotationsAttribute(ConstPool cp, int n, DataInputStream in)163*f1fbf3c2SXin Li     AnnotationsAttribute(ConstPool cp, int n, DataInputStream in)
164*f1fbf3c2SXin Li         throws IOException
165*f1fbf3c2SXin Li     {
166*f1fbf3c2SXin Li         super(cp, n, in);
167*f1fbf3c2SXin Li     }
168*f1fbf3c2SXin Li 
169*f1fbf3c2SXin Li     /**
170*f1fbf3c2SXin Li      * Returns <code>num_annotations</code>.
171*f1fbf3c2SXin Li      */
numAnnotations()172*f1fbf3c2SXin Li     public int numAnnotations() {
173*f1fbf3c2SXin Li         return ByteArray.readU16bit(info, 0);
174*f1fbf3c2SXin Li     }
175*f1fbf3c2SXin Li 
176*f1fbf3c2SXin Li     /**
177*f1fbf3c2SXin Li      * Copies this attribute and returns a new copy.
178*f1fbf3c2SXin Li      */
179*f1fbf3c2SXin Li     @Override
copy(ConstPool newCp, Map<String,String> classnames)180*f1fbf3c2SXin Li     public AttributeInfo copy(ConstPool newCp, Map<String,String> classnames) {
181*f1fbf3c2SXin Li         Copier copier = new Copier(info, constPool, newCp, classnames);
182*f1fbf3c2SXin Li         try {
183*f1fbf3c2SXin Li             copier.annotationArray();
184*f1fbf3c2SXin Li             return new AnnotationsAttribute(newCp, getName(), copier.close());
185*f1fbf3c2SXin Li         }
186*f1fbf3c2SXin Li         catch (Exception e) {
187*f1fbf3c2SXin Li             throw new RuntimeException(e);
188*f1fbf3c2SXin Li         }
189*f1fbf3c2SXin Li     }
190*f1fbf3c2SXin Li 
191*f1fbf3c2SXin Li     /**
192*f1fbf3c2SXin Li      * Parses the annotations and returns a data structure representing
193*f1fbf3c2SXin Li      * the annotation with the specified type.  See also
194*f1fbf3c2SXin Li      * <code>getAnnotations()</code> as to the returned data structure.
195*f1fbf3c2SXin Li      *
196*f1fbf3c2SXin Li      * @param type      the annotation type.
197*f1fbf3c2SXin Li      * @return null if the specified annotation type is not included.
198*f1fbf3c2SXin Li      * @see #getAnnotations()
199*f1fbf3c2SXin Li      */
getAnnotation(String type)200*f1fbf3c2SXin Li     public Annotation getAnnotation(String type) {
201*f1fbf3c2SXin Li         Annotation[] annotations = getAnnotations();
202*f1fbf3c2SXin Li         for (int i = 0; i < annotations.length; i++) {
203*f1fbf3c2SXin Li             if (annotations[i].getTypeName().equals(type))
204*f1fbf3c2SXin Li                 return annotations[i];
205*f1fbf3c2SXin Li         }
206*f1fbf3c2SXin Li 
207*f1fbf3c2SXin Li         return null;
208*f1fbf3c2SXin Li     }
209*f1fbf3c2SXin Li 
210*f1fbf3c2SXin Li     /**
211*f1fbf3c2SXin Li      * Adds an annotation.  If there is an annotation with the same type,
212*f1fbf3c2SXin Li      * it is removed before the new annotation is added.
213*f1fbf3c2SXin Li      *
214*f1fbf3c2SXin Li      * @param annotation        the added annotation.
215*f1fbf3c2SXin Li      */
addAnnotation(Annotation annotation)216*f1fbf3c2SXin Li     public void addAnnotation(Annotation annotation) {
217*f1fbf3c2SXin Li         String type = annotation.getTypeName();
218*f1fbf3c2SXin Li         Annotation[] annotations = getAnnotations();
219*f1fbf3c2SXin Li         for (int i = 0; i < annotations.length; i++) {
220*f1fbf3c2SXin Li             if (annotations[i].getTypeName().equals(type)) {
221*f1fbf3c2SXin Li                 annotations[i] = annotation;
222*f1fbf3c2SXin Li                 setAnnotations(annotations);
223*f1fbf3c2SXin Li                 return;
224*f1fbf3c2SXin Li             }
225*f1fbf3c2SXin Li         }
226*f1fbf3c2SXin Li 
227*f1fbf3c2SXin Li         Annotation[] newlist = new Annotation[annotations.length + 1];
228*f1fbf3c2SXin Li         System.arraycopy(annotations, 0, newlist, 0, annotations.length);
229*f1fbf3c2SXin Li         newlist[annotations.length] = annotation;
230*f1fbf3c2SXin Li         setAnnotations(newlist);
231*f1fbf3c2SXin Li     }
232*f1fbf3c2SXin Li 
233*f1fbf3c2SXin Li     /**
234*f1fbf3c2SXin Li      * Removes an annotation by type.
235*f1fbf3c2SXin Li      * After removing an annotation, if {@link #numAnnotations()} returns 0,
236*f1fbf3c2SXin Li      * this annotations attribute has to be removed.
237*f1fbf3c2SXin Li      *
238*f1fbf3c2SXin Li      * @param type        of annotation to remove
239*f1fbf3c2SXin Li      * @return whether an annotation with the given type has been removed
240*f1fbf3c2SXin Li      * @since 3.21
241*f1fbf3c2SXin Li      */
removeAnnotation(String type)242*f1fbf3c2SXin Li     public boolean removeAnnotation(String type) {
243*f1fbf3c2SXin Li         Annotation[] annotations = getAnnotations();
244*f1fbf3c2SXin Li         for (int i = 0; i < annotations.length; i++) {
245*f1fbf3c2SXin Li             if (annotations[i].getTypeName().equals(type)) {
246*f1fbf3c2SXin Li                 Annotation[] newlist = new Annotation[annotations.length - 1];
247*f1fbf3c2SXin Li                 System.arraycopy(annotations, 0, newlist, 0, i);
248*f1fbf3c2SXin Li                 if (i < annotations.length - 1) {
249*f1fbf3c2SXin Li                     System.arraycopy(annotations, i + 1, newlist, i,
250*f1fbf3c2SXin Li                                      annotations.length - i - 1);
251*f1fbf3c2SXin Li                 }
252*f1fbf3c2SXin Li                 setAnnotations(newlist);
253*f1fbf3c2SXin Li                 return true;
254*f1fbf3c2SXin Li             }
255*f1fbf3c2SXin Li         }
256*f1fbf3c2SXin Li         return false;
257*f1fbf3c2SXin Li     }
258*f1fbf3c2SXin Li 
259*f1fbf3c2SXin Li     /**
260*f1fbf3c2SXin Li      * Parses the annotations and returns a data structure representing
261*f1fbf3c2SXin Li      * that parsed annotations.  Note that changes of the node values of the
262*f1fbf3c2SXin Li      * returned tree are not reflected on the annotations represented by
263*f1fbf3c2SXin Li      * this object unless the tree is copied back to this object by
264*f1fbf3c2SXin Li      * <code>setAnnotations()</code>.
265*f1fbf3c2SXin Li      *
266*f1fbf3c2SXin Li      * @see #setAnnotations(Annotation[])
267*f1fbf3c2SXin Li      */
getAnnotations()268*f1fbf3c2SXin Li     public Annotation[] getAnnotations() {
269*f1fbf3c2SXin Li         try {
270*f1fbf3c2SXin Li             return new Parser(info, constPool).parseAnnotations();
271*f1fbf3c2SXin Li         }
272*f1fbf3c2SXin Li         catch (Exception e) {
273*f1fbf3c2SXin Li             throw new RuntimeException(e);
274*f1fbf3c2SXin Li         }
275*f1fbf3c2SXin Li     }
276*f1fbf3c2SXin Li 
277*f1fbf3c2SXin Li     /**
278*f1fbf3c2SXin Li      * Changes the annotations represented by this object according to
279*f1fbf3c2SXin Li      * the given array of <code>Annotation</code> objects.
280*f1fbf3c2SXin Li      *
281*f1fbf3c2SXin Li      * @param annotations           the data structure representing the
282*f1fbf3c2SXin Li      *                              new annotations.
283*f1fbf3c2SXin Li      */
setAnnotations(Annotation[] annotations)284*f1fbf3c2SXin Li     public void setAnnotations(Annotation[] annotations) {
285*f1fbf3c2SXin Li         ByteArrayOutputStream output = new ByteArrayOutputStream();
286*f1fbf3c2SXin Li         AnnotationsWriter writer = new AnnotationsWriter(output, constPool);
287*f1fbf3c2SXin Li         try {
288*f1fbf3c2SXin Li             int n = annotations.length;
289*f1fbf3c2SXin Li             writer.numAnnotations(n);
290*f1fbf3c2SXin Li             for (int i = 0; i < n; ++i)
291*f1fbf3c2SXin Li                 annotations[i].write(writer);
292*f1fbf3c2SXin Li 
293*f1fbf3c2SXin Li             writer.close();
294*f1fbf3c2SXin Li         }
295*f1fbf3c2SXin Li         catch (IOException e) {
296*f1fbf3c2SXin Li             throw new RuntimeException(e);      // should never reach here.
297*f1fbf3c2SXin Li         }
298*f1fbf3c2SXin Li 
299*f1fbf3c2SXin Li         set(output.toByteArray());
300*f1fbf3c2SXin Li     }
301*f1fbf3c2SXin Li 
302*f1fbf3c2SXin Li     /**
303*f1fbf3c2SXin Li      * Changes the annotations.  A call to this method is equivalent to:
304*f1fbf3c2SXin Li      * <pre>setAnnotations(new Annotation[] { annotation })</pre>
305*f1fbf3c2SXin Li      *
306*f1fbf3c2SXin Li      * @param annotation    the data structure representing
307*f1fbf3c2SXin Li      *                      the new annotation.
308*f1fbf3c2SXin Li      */
setAnnotation(Annotation annotation)309*f1fbf3c2SXin Li     public void setAnnotation(Annotation annotation) {
310*f1fbf3c2SXin Li         setAnnotations(new Annotation[] { annotation });
311*f1fbf3c2SXin Li     }
312*f1fbf3c2SXin Li 
313*f1fbf3c2SXin Li     /**
314*f1fbf3c2SXin Li      * @param oldname       a JVM class name.
315*f1fbf3c2SXin Li      * @param newname       a JVM class name.
316*f1fbf3c2SXin Li      */
317*f1fbf3c2SXin Li     @Override
renameClass(String oldname, String newname)318*f1fbf3c2SXin Li     void renameClass(String oldname, String newname) {
319*f1fbf3c2SXin Li         Map<String,String> map = new HashMap<String,String>();
320*f1fbf3c2SXin Li         map.put(oldname, newname);
321*f1fbf3c2SXin Li         renameClass(map);
322*f1fbf3c2SXin Li     }
323*f1fbf3c2SXin Li 
324*f1fbf3c2SXin Li     @Override
renameClass(Map<String,String> classnames)325*f1fbf3c2SXin Li     void renameClass(Map<String,String> classnames) {
326*f1fbf3c2SXin Li         Renamer renamer = new Renamer(info, getConstPool(), classnames);
327*f1fbf3c2SXin Li         try {
328*f1fbf3c2SXin Li             renamer.annotationArray();
329*f1fbf3c2SXin Li         } catch (Exception e) {
330*f1fbf3c2SXin Li             throw new RuntimeException(e);
331*f1fbf3c2SXin Li         }
332*f1fbf3c2SXin Li     }
333*f1fbf3c2SXin Li 
334*f1fbf3c2SXin Li     @Override
getRefClasses(Map<String,String> classnames)335*f1fbf3c2SXin Li     void getRefClasses(Map<String,String> classnames) { renameClass(classnames); }
336*f1fbf3c2SXin Li 
337*f1fbf3c2SXin Li     /**
338*f1fbf3c2SXin Li      * Returns a string representation of this object.
339*f1fbf3c2SXin Li      */
340*f1fbf3c2SXin Li     @Override
toString()341*f1fbf3c2SXin Li     public String toString() {
342*f1fbf3c2SXin Li         Annotation[] a = getAnnotations();
343*f1fbf3c2SXin Li         StringBuilder sbuf = new StringBuilder();
344*f1fbf3c2SXin Li         int i = 0;
345*f1fbf3c2SXin Li         while (i < a.length) {
346*f1fbf3c2SXin Li             sbuf.append(a[i++].toString());
347*f1fbf3c2SXin Li             if (i != a.length)
348*f1fbf3c2SXin Li                 sbuf.append(", ");
349*f1fbf3c2SXin Li         }
350*f1fbf3c2SXin Li 
351*f1fbf3c2SXin Li         return sbuf.toString();
352*f1fbf3c2SXin Li     }
353*f1fbf3c2SXin Li 
354*f1fbf3c2SXin Li     static class Walker {
355*f1fbf3c2SXin Li         byte[] info;
356*f1fbf3c2SXin Li 
Walker(byte[] attrInfo)357*f1fbf3c2SXin Li         Walker(byte[] attrInfo) {
358*f1fbf3c2SXin Li             info = attrInfo;
359*f1fbf3c2SXin Li         }
360*f1fbf3c2SXin Li 
parameters()361*f1fbf3c2SXin Li         final void parameters() throws Exception {
362*f1fbf3c2SXin Li             int numParam = info[0] & 0xff;
363*f1fbf3c2SXin Li             parameters(numParam, 1);
364*f1fbf3c2SXin Li         }
365*f1fbf3c2SXin Li 
parameters(int numParam, int pos)366*f1fbf3c2SXin Li         void parameters(int numParam, int pos) throws Exception {
367*f1fbf3c2SXin Li             for (int i = 0; i < numParam; ++i)
368*f1fbf3c2SXin Li                 pos = annotationArray(pos);
369*f1fbf3c2SXin Li         }
370*f1fbf3c2SXin Li 
annotationArray()371*f1fbf3c2SXin Li         final void annotationArray() throws Exception {
372*f1fbf3c2SXin Li             annotationArray(0);
373*f1fbf3c2SXin Li         }
374*f1fbf3c2SXin Li 
annotationArray(int pos)375*f1fbf3c2SXin Li         final int annotationArray(int pos) throws Exception {
376*f1fbf3c2SXin Li             int num = ByteArray.readU16bit(info, pos);
377*f1fbf3c2SXin Li             return annotationArray(pos + 2, num);
378*f1fbf3c2SXin Li         }
379*f1fbf3c2SXin Li 
annotationArray(int pos, int num)380*f1fbf3c2SXin Li         int annotationArray(int pos, int num) throws Exception {
381*f1fbf3c2SXin Li             for (int i = 0; i < num; ++i)
382*f1fbf3c2SXin Li                 pos = annotation(pos);
383*f1fbf3c2SXin Li 
384*f1fbf3c2SXin Li             return pos;
385*f1fbf3c2SXin Li         }
386*f1fbf3c2SXin Li 
annotation(int pos)387*f1fbf3c2SXin Li         final int annotation(int pos) throws Exception {
388*f1fbf3c2SXin Li             int type = ByteArray.readU16bit(info, pos);
389*f1fbf3c2SXin Li             int numPairs = ByteArray.readU16bit(info, pos + 2);
390*f1fbf3c2SXin Li             return annotation(pos + 4, type, numPairs);
391*f1fbf3c2SXin Li         }
392*f1fbf3c2SXin Li 
annotation(int pos, int type, int numPairs)393*f1fbf3c2SXin Li         int annotation(int pos, int type, int numPairs) throws Exception {
394*f1fbf3c2SXin Li             for (int j = 0; j < numPairs; ++j)
395*f1fbf3c2SXin Li                 pos = memberValuePair(pos);
396*f1fbf3c2SXin Li 
397*f1fbf3c2SXin Li             return pos;
398*f1fbf3c2SXin Li         }
399*f1fbf3c2SXin Li 
400*f1fbf3c2SXin Li         /**
401*f1fbf3c2SXin Li          * {@code element_value_paris}
402*f1fbf3c2SXin Li          */
memberValuePair(int pos)403*f1fbf3c2SXin Li         final int memberValuePair(int pos) throws Exception {
404*f1fbf3c2SXin Li             int nameIndex = ByteArray.readU16bit(info, pos);
405*f1fbf3c2SXin Li             return memberValuePair(pos + 2, nameIndex);
406*f1fbf3c2SXin Li         }
407*f1fbf3c2SXin Li 
408*f1fbf3c2SXin Li         /**
409*f1fbf3c2SXin Li          * {@code element_value_paris[]}
410*f1fbf3c2SXin Li          */
memberValuePair(int pos, int nameIndex)411*f1fbf3c2SXin Li         int memberValuePair(int pos, int nameIndex) throws Exception {
412*f1fbf3c2SXin Li             return memberValue(pos);
413*f1fbf3c2SXin Li         }
414*f1fbf3c2SXin Li 
415*f1fbf3c2SXin Li         /**
416*f1fbf3c2SXin Li          * {@code element_value}
417*f1fbf3c2SXin Li          */
memberValue(int pos)418*f1fbf3c2SXin Li         final int memberValue(int pos) throws Exception {
419*f1fbf3c2SXin Li             int tag = info[pos] & 0xff;
420*f1fbf3c2SXin Li             if (tag == 'e') {
421*f1fbf3c2SXin Li                 int typeNameIndex = ByteArray.readU16bit(info, pos + 1);
422*f1fbf3c2SXin Li                 int constNameIndex = ByteArray.readU16bit(info, pos + 3);
423*f1fbf3c2SXin Li                 enumMemberValue(pos, typeNameIndex, constNameIndex);
424*f1fbf3c2SXin Li                 return pos + 5;
425*f1fbf3c2SXin Li             }
426*f1fbf3c2SXin Li             else if (tag == 'c') {
427*f1fbf3c2SXin Li                 int index = ByteArray.readU16bit(info, pos + 1);
428*f1fbf3c2SXin Li                 classMemberValue(pos, index);
429*f1fbf3c2SXin Li                 return pos + 3;
430*f1fbf3c2SXin Li             }
431*f1fbf3c2SXin Li             else if (tag == '@')
432*f1fbf3c2SXin Li                 return annotationMemberValue(pos + 1);
433*f1fbf3c2SXin Li             else if (tag == '[') {
434*f1fbf3c2SXin Li                 int num = ByteArray.readU16bit(info, pos + 1);
435*f1fbf3c2SXin Li                 return arrayMemberValue(pos + 3, num);
436*f1fbf3c2SXin Li             }
437*f1fbf3c2SXin Li             else { // primitive types or String.
438*f1fbf3c2SXin Li                 int index = ByteArray.readU16bit(info, pos + 1);
439*f1fbf3c2SXin Li                 constValueMember(tag, index);
440*f1fbf3c2SXin Li                 return pos + 3;
441*f1fbf3c2SXin Li             }
442*f1fbf3c2SXin Li         }
443*f1fbf3c2SXin Li 
444*f1fbf3c2SXin Li         /**
445*f1fbf3c2SXin Li          * {@code const_value_index}
446*f1fbf3c2SXin Li          */
constValueMember(int tag, int index)447*f1fbf3c2SXin Li         void constValueMember(int tag, int index) throws Exception {}
448*f1fbf3c2SXin Li 
449*f1fbf3c2SXin Li         /**
450*f1fbf3c2SXin Li          * {@code enum_const_value}
451*f1fbf3c2SXin Li          */
enumMemberValue(int pos, int typeNameIndex, int constNameIndex)452*f1fbf3c2SXin Li         void enumMemberValue(int pos, int typeNameIndex, int constNameIndex)
453*f1fbf3c2SXin Li             throws Exception {
454*f1fbf3c2SXin Li         }
455*f1fbf3c2SXin Li 
456*f1fbf3c2SXin Li         /**
457*f1fbf3c2SXin Li          * {@code class_info_index}
458*f1fbf3c2SXin Li          */
classMemberValue(int pos, int index)459*f1fbf3c2SXin Li         void classMemberValue(int pos, int index) throws Exception {}
460*f1fbf3c2SXin Li 
461*f1fbf3c2SXin Li         /**
462*f1fbf3c2SXin Li          * {@code annotation_value}
463*f1fbf3c2SXin Li          */
annotationMemberValue(int pos)464*f1fbf3c2SXin Li         int annotationMemberValue(int pos) throws Exception {
465*f1fbf3c2SXin Li             return annotation(pos);
466*f1fbf3c2SXin Li         }
467*f1fbf3c2SXin Li 
468*f1fbf3c2SXin Li         /**
469*f1fbf3c2SXin Li          * {@code array_value}
470*f1fbf3c2SXin Li          */
arrayMemberValue(int pos, int num)471*f1fbf3c2SXin Li         int arrayMemberValue(int pos, int num) throws Exception {
472*f1fbf3c2SXin Li             for (int i = 0; i < num; ++i) {
473*f1fbf3c2SXin Li                 pos = memberValue(pos);
474*f1fbf3c2SXin Li             }
475*f1fbf3c2SXin Li 
476*f1fbf3c2SXin Li             return pos;
477*f1fbf3c2SXin Li         }
478*f1fbf3c2SXin Li     }
479*f1fbf3c2SXin Li 
480*f1fbf3c2SXin Li     static class Renamer extends Walker {
481*f1fbf3c2SXin Li         ConstPool cpool;
482*f1fbf3c2SXin Li         Map<String,String> classnames;
483*f1fbf3c2SXin Li 
484*f1fbf3c2SXin Li         /**
485*f1fbf3c2SXin Li          * Constructs a renamer.  It renames some class names
486*f1fbf3c2SXin Li          * into the new names specified by <code>map</code>.
487*f1fbf3c2SXin Li          *
488*f1fbf3c2SXin Li          * @param info      the annotations attribute.
489*f1fbf3c2SXin Li          * @param cp        the constant pool.
490*f1fbf3c2SXin Li          * @param map       pairs of replaced and substituted class names.
491*f1fbf3c2SXin Li          *                  It can be null.
492*f1fbf3c2SXin Li          */
Renamer(byte[] info, ConstPool cp, Map<String,String> map)493*f1fbf3c2SXin Li         Renamer(byte[] info, ConstPool cp, Map<String,String> map) {
494*f1fbf3c2SXin Li             super(info);
495*f1fbf3c2SXin Li             cpool = cp;
496*f1fbf3c2SXin Li             classnames = map;
497*f1fbf3c2SXin Li         }
498*f1fbf3c2SXin Li 
499*f1fbf3c2SXin Li         @Override
annotation(int pos, int type, int numPairs)500*f1fbf3c2SXin Li         int annotation(int pos, int type, int numPairs) throws Exception {
501*f1fbf3c2SXin Li             renameType(pos - 4, type);
502*f1fbf3c2SXin Li             return super.annotation(pos, type, numPairs);
503*f1fbf3c2SXin Li         }
504*f1fbf3c2SXin Li 
505*f1fbf3c2SXin Li         @Override
enumMemberValue(int pos, int typeNameIndex, int constNameIndex)506*f1fbf3c2SXin Li         void enumMemberValue(int pos, int typeNameIndex, int constNameIndex)
507*f1fbf3c2SXin Li             throws Exception
508*f1fbf3c2SXin Li         {
509*f1fbf3c2SXin Li             renameType(pos + 1, typeNameIndex);
510*f1fbf3c2SXin Li             super.enumMemberValue(pos, typeNameIndex, constNameIndex);
511*f1fbf3c2SXin Li         }
512*f1fbf3c2SXin Li 
513*f1fbf3c2SXin Li         @Override
classMemberValue(int pos, int index)514*f1fbf3c2SXin Li         void classMemberValue(int pos, int index) throws Exception {
515*f1fbf3c2SXin Li             renameType(pos + 1, index);
516*f1fbf3c2SXin Li             super.classMemberValue(pos, index);
517*f1fbf3c2SXin Li         }
518*f1fbf3c2SXin Li 
renameType(int pos, int index)519*f1fbf3c2SXin Li         private void renameType(int pos, int index) {
520*f1fbf3c2SXin Li             String name = cpool.getUtf8Info(index);
521*f1fbf3c2SXin Li             String newName = Descriptor.rename(name, classnames);
522*f1fbf3c2SXin Li             if (!name.equals(newName)) {
523*f1fbf3c2SXin Li                 int index2 = cpool.addUtf8Info(newName);
524*f1fbf3c2SXin Li                 ByteArray.write16bit(index2, info, pos);
525*f1fbf3c2SXin Li             }
526*f1fbf3c2SXin Li         }
527*f1fbf3c2SXin Li     }
528*f1fbf3c2SXin Li 
529*f1fbf3c2SXin Li     static class Copier extends Walker {
530*f1fbf3c2SXin Li         ByteArrayOutputStream output;
531*f1fbf3c2SXin Li         AnnotationsWriter writer;
532*f1fbf3c2SXin Li         ConstPool srcPool, destPool;
533*f1fbf3c2SXin Li         Map<String,String> classnames;
534*f1fbf3c2SXin Li 
535*f1fbf3c2SXin Li         /**
536*f1fbf3c2SXin Li          * Constructs a copier.  This copier renames some class names
537*f1fbf3c2SXin Li          * into the new names specified by <code>map</code> when it copies
538*f1fbf3c2SXin Li          * an annotation attribute.
539*f1fbf3c2SXin Li          *
540*f1fbf3c2SXin Li          * @param info      the source attribute.
541*f1fbf3c2SXin Li          * @param src       the constant pool of the source class.
542*f1fbf3c2SXin Li          * @param dest      the constant pool of the destination class.
543*f1fbf3c2SXin Li          * @param map       pairs of replaced and substituted class names.
544*f1fbf3c2SXin Li          *                  It can be null.
545*f1fbf3c2SXin Li          */
Copier(byte[] info, ConstPool src, ConstPool dest, Map<String,String> map)546*f1fbf3c2SXin Li         Copier(byte[] info, ConstPool src, ConstPool dest, Map<String,String> map) {
547*f1fbf3c2SXin Li             this(info, src, dest, map, true);
548*f1fbf3c2SXin Li         }
549*f1fbf3c2SXin Li 
Copier(byte[] info, ConstPool src, ConstPool dest, Map<String,String> map, boolean makeWriter)550*f1fbf3c2SXin Li         Copier(byte[] info, ConstPool src, ConstPool dest, Map<String,String> map, boolean makeWriter) {
551*f1fbf3c2SXin Li             super(info);
552*f1fbf3c2SXin Li             output = new ByteArrayOutputStream();
553*f1fbf3c2SXin Li             if (makeWriter)
554*f1fbf3c2SXin Li                 writer = new AnnotationsWriter(output, dest);
555*f1fbf3c2SXin Li 
556*f1fbf3c2SXin Li             srcPool = src;
557*f1fbf3c2SXin Li             destPool = dest;
558*f1fbf3c2SXin Li             classnames = map;
559*f1fbf3c2SXin Li         }
560*f1fbf3c2SXin Li 
close()561*f1fbf3c2SXin Li         byte[] close() throws IOException {
562*f1fbf3c2SXin Li             writer.close();
563*f1fbf3c2SXin Li             return output.toByteArray();
564*f1fbf3c2SXin Li         }
565*f1fbf3c2SXin Li 
566*f1fbf3c2SXin Li         @Override
parameters(int numParam, int pos)567*f1fbf3c2SXin Li         void parameters(int numParam, int pos) throws Exception {
568*f1fbf3c2SXin Li             writer.numParameters(numParam);
569*f1fbf3c2SXin Li             super.parameters(numParam, pos);
570*f1fbf3c2SXin Li         }
571*f1fbf3c2SXin Li 
572*f1fbf3c2SXin Li         @Override
annotationArray(int pos, int num)573*f1fbf3c2SXin Li         int annotationArray(int pos, int num) throws Exception {
574*f1fbf3c2SXin Li             writer.numAnnotations(num);
575*f1fbf3c2SXin Li             return super.annotationArray(pos, num);
576*f1fbf3c2SXin Li         }
577*f1fbf3c2SXin Li 
578*f1fbf3c2SXin Li         @Override
annotation(int pos, int type, int numPairs)579*f1fbf3c2SXin Li         int annotation(int pos, int type, int numPairs) throws Exception {
580*f1fbf3c2SXin Li             writer.annotation(copyType(type), numPairs);
581*f1fbf3c2SXin Li             return super.annotation(pos, type, numPairs);
582*f1fbf3c2SXin Li         }
583*f1fbf3c2SXin Li 
584*f1fbf3c2SXin Li         @Override
memberValuePair(int pos, int nameIndex)585*f1fbf3c2SXin Li         int memberValuePair(int pos, int nameIndex) throws Exception {
586*f1fbf3c2SXin Li             writer.memberValuePair(copy(nameIndex));
587*f1fbf3c2SXin Li             return super.memberValuePair(pos, nameIndex);
588*f1fbf3c2SXin Li         }
589*f1fbf3c2SXin Li 
590*f1fbf3c2SXin Li         @Override
constValueMember(int tag, int index)591*f1fbf3c2SXin Li         void constValueMember(int tag, int index) throws Exception {
592*f1fbf3c2SXin Li             writer.constValueIndex(tag, copy(index));
593*f1fbf3c2SXin Li             super.constValueMember(tag, index);
594*f1fbf3c2SXin Li         }
595*f1fbf3c2SXin Li 
596*f1fbf3c2SXin Li         @Override
enumMemberValue(int pos, int typeNameIndex, int constNameIndex)597*f1fbf3c2SXin Li         void enumMemberValue(int pos, int typeNameIndex, int constNameIndex)
598*f1fbf3c2SXin Li             throws Exception
599*f1fbf3c2SXin Li         {
600*f1fbf3c2SXin Li             writer.enumConstValue(copyType(typeNameIndex), copy(constNameIndex));
601*f1fbf3c2SXin Li             super.enumMemberValue(pos, typeNameIndex, constNameIndex);
602*f1fbf3c2SXin Li         }
603*f1fbf3c2SXin Li 
604*f1fbf3c2SXin Li         @Override
classMemberValue(int pos, int index)605*f1fbf3c2SXin Li         void classMemberValue(int pos, int index) throws Exception {
606*f1fbf3c2SXin Li             writer.classInfoIndex(copyType(index));
607*f1fbf3c2SXin Li             super.classMemberValue(pos, index);
608*f1fbf3c2SXin Li         }
609*f1fbf3c2SXin Li 
610*f1fbf3c2SXin Li         @Override
annotationMemberValue(int pos)611*f1fbf3c2SXin Li         int annotationMemberValue(int pos) throws Exception {
612*f1fbf3c2SXin Li             writer.annotationValue();
613*f1fbf3c2SXin Li             return super.annotationMemberValue(pos);
614*f1fbf3c2SXin Li         }
615*f1fbf3c2SXin Li 
616*f1fbf3c2SXin Li         @Override
arrayMemberValue(int pos, int num)617*f1fbf3c2SXin Li         int arrayMemberValue(int pos, int num) throws Exception {
618*f1fbf3c2SXin Li             writer.arrayValue(num);
619*f1fbf3c2SXin Li             return super.arrayMemberValue(pos, num);
620*f1fbf3c2SXin Li         }
621*f1fbf3c2SXin Li 
622*f1fbf3c2SXin Li         /**
623*f1fbf3c2SXin Li          * Copies a constant pool entry into the destination constant pool
624*f1fbf3c2SXin Li          * and returns the index of the copied entry.
625*f1fbf3c2SXin Li          *
626*f1fbf3c2SXin Li          * @param srcIndex      the index of the copied entry into the source
627*f1fbf3c2SXin Li          *                      constant pool.
628*f1fbf3c2SXin Li          * @return the index of the copied item into the destination
629*f1fbf3c2SXin Li          *         constant pool.
630*f1fbf3c2SXin Li          */
copy(int srcIndex)631*f1fbf3c2SXin Li         int copy(int srcIndex) {
632*f1fbf3c2SXin Li             return srcPool.copy(srcIndex, destPool, classnames);
633*f1fbf3c2SXin Li         }
634*f1fbf3c2SXin Li 
635*f1fbf3c2SXin Li         /**
636*f1fbf3c2SXin Li          * Copies a constant pool entry into the destination constant pool
637*f1fbf3c2SXin Li          * and returns the index of the copied entry.  That entry must be
638*f1fbf3c2SXin Li          * a Utf8Info representing a class name in the L<class name>; form.
639*f1fbf3c2SXin Li          *
640*f1fbf3c2SXin Li          * @param srcIndex  the index of the copied entry into the source
641*f1fbf3c2SXin Li          *                  constant pool.
642*f1fbf3c2SXin Li          * @return          the index of the copied item into the destination
643*f1fbf3c2SXin Li          *                  constant pool.
644*f1fbf3c2SXin Li          */
copyType(int srcIndex)645*f1fbf3c2SXin Li         int copyType(int srcIndex) {
646*f1fbf3c2SXin Li             String name = srcPool.getUtf8Info(srcIndex);
647*f1fbf3c2SXin Li             String newName = Descriptor.rename(name, classnames);
648*f1fbf3c2SXin Li             return destPool.addUtf8Info(newName);
649*f1fbf3c2SXin Li         }
650*f1fbf3c2SXin Li     }
651*f1fbf3c2SXin Li 
652*f1fbf3c2SXin Li     static class Parser extends Walker {
653*f1fbf3c2SXin Li         ConstPool pool;
654*f1fbf3c2SXin Li         Annotation[][] allParams;   // all parameters
655*f1fbf3c2SXin Li         Annotation[] allAnno;       // all annotations
656*f1fbf3c2SXin Li         Annotation currentAnno;     // current annotation
657*f1fbf3c2SXin Li         MemberValue currentMember;  // current member
658*f1fbf3c2SXin Li 
659*f1fbf3c2SXin Li         /**
660*f1fbf3c2SXin Li          * Constructs a parser.  This parser constructs a parse tree of
661*f1fbf3c2SXin Li          * the annotations.
662*f1fbf3c2SXin Li          *
663*f1fbf3c2SXin Li          * @param info      the attribute.
664*f1fbf3c2SXin Li          * @param src       the constant pool.
665*f1fbf3c2SXin Li          */
Parser(byte[] info, ConstPool cp)666*f1fbf3c2SXin Li         Parser(byte[] info, ConstPool cp) {
667*f1fbf3c2SXin Li             super(info);
668*f1fbf3c2SXin Li             pool = cp;
669*f1fbf3c2SXin Li         }
670*f1fbf3c2SXin Li 
parseParameters()671*f1fbf3c2SXin Li         Annotation[][] parseParameters() throws Exception {
672*f1fbf3c2SXin Li             parameters();
673*f1fbf3c2SXin Li             return allParams;
674*f1fbf3c2SXin Li         }
675*f1fbf3c2SXin Li 
parseAnnotations()676*f1fbf3c2SXin Li         Annotation[] parseAnnotations() throws Exception {
677*f1fbf3c2SXin Li             annotationArray();
678*f1fbf3c2SXin Li             return allAnno;
679*f1fbf3c2SXin Li         }
680*f1fbf3c2SXin Li 
parseMemberValue()681*f1fbf3c2SXin Li         MemberValue parseMemberValue() throws Exception {
682*f1fbf3c2SXin Li             memberValue(0);
683*f1fbf3c2SXin Li             return currentMember;
684*f1fbf3c2SXin Li         }
685*f1fbf3c2SXin Li 
686*f1fbf3c2SXin Li         @Override
parameters(int numParam, int pos)687*f1fbf3c2SXin Li         void parameters(int numParam, int pos) throws Exception {
688*f1fbf3c2SXin Li             Annotation[][] params = new Annotation[numParam][];
689*f1fbf3c2SXin Li             for (int i = 0; i < numParam; ++i) {
690*f1fbf3c2SXin Li                 pos = annotationArray(pos);
691*f1fbf3c2SXin Li                 params[i] = allAnno;
692*f1fbf3c2SXin Li             }
693*f1fbf3c2SXin Li 
694*f1fbf3c2SXin Li             allParams = params;
695*f1fbf3c2SXin Li         }
696*f1fbf3c2SXin Li 
697*f1fbf3c2SXin Li         @Override
annotationArray(int pos, int num)698*f1fbf3c2SXin Li         int annotationArray(int pos, int num) throws Exception {
699*f1fbf3c2SXin Li             Annotation[] array = new Annotation[num];
700*f1fbf3c2SXin Li             for (int i = 0; i < num; ++i) {
701*f1fbf3c2SXin Li                 pos = annotation(pos);
702*f1fbf3c2SXin Li                 array[i] = currentAnno;
703*f1fbf3c2SXin Li             }
704*f1fbf3c2SXin Li 
705*f1fbf3c2SXin Li             allAnno = array;
706*f1fbf3c2SXin Li             return pos;
707*f1fbf3c2SXin Li         }
708*f1fbf3c2SXin Li 
709*f1fbf3c2SXin Li         @Override
annotation(int pos, int type, int numPairs)710*f1fbf3c2SXin Li         int annotation(int pos, int type, int numPairs) throws Exception {
711*f1fbf3c2SXin Li             currentAnno = new Annotation(type, pool);
712*f1fbf3c2SXin Li             return super.annotation(pos, type, numPairs);
713*f1fbf3c2SXin Li         }
714*f1fbf3c2SXin Li 
715*f1fbf3c2SXin Li         @Override
memberValuePair(int pos, int nameIndex)716*f1fbf3c2SXin Li         int memberValuePair(int pos, int nameIndex) throws Exception {
717*f1fbf3c2SXin Li             pos = super.memberValuePair(pos, nameIndex);
718*f1fbf3c2SXin Li             currentAnno.addMemberValue(nameIndex, currentMember);
719*f1fbf3c2SXin Li             return pos;
720*f1fbf3c2SXin Li         }
721*f1fbf3c2SXin Li 
722*f1fbf3c2SXin Li         @Override
constValueMember(int tag, int index)723*f1fbf3c2SXin Li         void constValueMember(int tag, int index) throws Exception {
724*f1fbf3c2SXin Li             MemberValue m;
725*f1fbf3c2SXin Li             ConstPool cp = pool;
726*f1fbf3c2SXin Li             switch (tag) {
727*f1fbf3c2SXin Li             case 'B' :
728*f1fbf3c2SXin Li                 m = new ByteMemberValue(index, cp);
729*f1fbf3c2SXin Li                 break;
730*f1fbf3c2SXin Li             case 'C' :
731*f1fbf3c2SXin Li                 m = new CharMemberValue(index, cp);
732*f1fbf3c2SXin Li                 break;
733*f1fbf3c2SXin Li             case 'D' :
734*f1fbf3c2SXin Li                 m = new DoubleMemberValue(index, cp);
735*f1fbf3c2SXin Li                 break;
736*f1fbf3c2SXin Li             case 'F' :
737*f1fbf3c2SXin Li                 m = new FloatMemberValue(index, cp);
738*f1fbf3c2SXin Li                 break;
739*f1fbf3c2SXin Li             case 'I' :
740*f1fbf3c2SXin Li                 m = new IntegerMemberValue(index, cp);
741*f1fbf3c2SXin Li                 break;
742*f1fbf3c2SXin Li             case 'J' :
743*f1fbf3c2SXin Li                 m = new LongMemberValue(index, cp);
744*f1fbf3c2SXin Li                 break;
745*f1fbf3c2SXin Li             case 'S' :
746*f1fbf3c2SXin Li                 m = new ShortMemberValue(index, cp);
747*f1fbf3c2SXin Li                 break;
748*f1fbf3c2SXin Li             case 'Z' :
749*f1fbf3c2SXin Li                 m = new BooleanMemberValue(index, cp);
750*f1fbf3c2SXin Li                 break;
751*f1fbf3c2SXin Li             case 's' :
752*f1fbf3c2SXin Li                 m = new StringMemberValue(index, cp);
753*f1fbf3c2SXin Li                 break;
754*f1fbf3c2SXin Li             default :
755*f1fbf3c2SXin Li                 throw new RuntimeException("unknown tag:" + tag);
756*f1fbf3c2SXin Li             }
757*f1fbf3c2SXin Li 
758*f1fbf3c2SXin Li             currentMember = m;
759*f1fbf3c2SXin Li             super.constValueMember(tag, index);
760*f1fbf3c2SXin Li         }
761*f1fbf3c2SXin Li 
762*f1fbf3c2SXin Li         @Override
enumMemberValue(int pos, int typeNameIndex, int constNameIndex)763*f1fbf3c2SXin Li         void enumMemberValue(int pos, int typeNameIndex, int constNameIndex)
764*f1fbf3c2SXin Li             throws Exception
765*f1fbf3c2SXin Li         {
766*f1fbf3c2SXin Li             currentMember = new EnumMemberValue(typeNameIndex,
767*f1fbf3c2SXin Li                                               constNameIndex, pool);
768*f1fbf3c2SXin Li             super.enumMemberValue(pos, typeNameIndex, constNameIndex);
769*f1fbf3c2SXin Li         }
770*f1fbf3c2SXin Li 
771*f1fbf3c2SXin Li         @Override
classMemberValue(int pos, int index)772*f1fbf3c2SXin Li         void classMemberValue(int pos, int index) throws Exception {
773*f1fbf3c2SXin Li             currentMember = new ClassMemberValue(index, pool);
774*f1fbf3c2SXin Li             super.classMemberValue(pos, index);
775*f1fbf3c2SXin Li         }
776*f1fbf3c2SXin Li 
777*f1fbf3c2SXin Li         @Override
annotationMemberValue(int pos)778*f1fbf3c2SXin Li         int annotationMemberValue(int pos) throws Exception {
779*f1fbf3c2SXin Li             Annotation anno = currentAnno;
780*f1fbf3c2SXin Li             pos = super.annotationMemberValue(pos);
781*f1fbf3c2SXin Li             currentMember = new AnnotationMemberValue(currentAnno, pool);
782*f1fbf3c2SXin Li             currentAnno = anno;
783*f1fbf3c2SXin Li             return pos;
784*f1fbf3c2SXin Li         }
785*f1fbf3c2SXin Li 
786*f1fbf3c2SXin Li         @Override
arrayMemberValue(int pos, int num)787*f1fbf3c2SXin Li         int arrayMemberValue(int pos, int num) throws Exception {
788*f1fbf3c2SXin Li             ArrayMemberValue amv = new ArrayMemberValue(pool);
789*f1fbf3c2SXin Li             MemberValue[] elements = new MemberValue[num];
790*f1fbf3c2SXin Li             for (int i = 0; i < num; ++i) {
791*f1fbf3c2SXin Li                 pos = memberValue(pos);
792*f1fbf3c2SXin Li                 elements[i] = currentMember;
793*f1fbf3c2SXin Li             }
794*f1fbf3c2SXin Li 
795*f1fbf3c2SXin Li             amv.setValue(elements);
796*f1fbf3c2SXin Li             currentMember = amv;
797*f1fbf3c2SXin Li             return pos;
798*f1fbf3c2SXin Li         }
799*f1fbf3c2SXin Li     }
800*f1fbf3c2SXin Li }
801