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 * @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