Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java
38867 views
/*1* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package xmlkit; // -*- mode: java; indent-tabs-mode: nil -*-2526import com.sun.tools.classfile.AccessFlags;27import com.sun.tools.classfile.Annotation;28import com.sun.tools.classfile.Annotation.*;29import com.sun.tools.classfile.AnnotationDefault_attribute;30import com.sun.tools.classfile.Attribute;31import com.sun.tools.classfile.Attributes;32import com.sun.tools.classfile.BootstrapMethods_attribute;33import com.sun.tools.classfile.CharacterRangeTable_attribute;34import com.sun.tools.classfile.ClassFile;35import com.sun.tools.classfile.Code_attribute;36import com.sun.tools.classfile.CompilationID_attribute;37import com.sun.tools.classfile.ConstantPool;38import com.sun.tools.classfile.ConstantPool.*;39import com.sun.tools.classfile.ConstantPoolException;40import com.sun.tools.classfile.ConstantValue_attribute;41import com.sun.tools.classfile.DefaultAttribute;42import com.sun.tools.classfile.Deprecated_attribute;43import com.sun.tools.classfile.Descriptor.InvalidDescriptor;44import com.sun.tools.classfile.EnclosingMethod_attribute;45import com.sun.tools.classfile.Exceptions_attribute;46import com.sun.tools.classfile.Field;47import com.sun.tools.classfile.InnerClasses_attribute;48import com.sun.tools.classfile.InnerClasses_attribute.Info;49import com.sun.tools.classfile.Instruction;50import com.sun.tools.classfile.Instruction.TypeKind;51import com.sun.tools.classfile.LineNumberTable_attribute;52import com.sun.tools.classfile.LocalVariableTable_attribute;53import com.sun.tools.classfile.LocalVariableTypeTable_attribute;54import com.sun.tools.classfile.Method;55import com.sun.tools.classfile.MethodParameters_attribute;56import com.sun.tools.classfile.Opcode;57import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute;58import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute;59import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute;60import com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute;61import com.sun.tools.classfile.RuntimeVisibleParameterAnnotations_attribute;62import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute;63import com.sun.tools.classfile.Signature_attribute;64import com.sun.tools.classfile.SourceDebugExtension_attribute;65import com.sun.tools.classfile.SourceFile_attribute;66import com.sun.tools.classfile.SourceID_attribute;67import com.sun.tools.classfile.StackMapTable_attribute;68import com.sun.tools.classfile.StackMapTable_attribute.*;69import com.sun.tools.classfile.StackMap_attribute;70import com.sun.tools.classfile.Synthetic_attribute;71import com.sun.tools.classfile.TypeAnnotation;72import com.sun.tools.classfile.TypeAnnotation.Position;73import static com.sun.tools.classfile.TypeAnnotation.TargetType.THROWS;74import java.util.*;75import java.io.*;76import java.util.jar.JarEntry;77import java.util.jar.JarFile;78import xmlkit.XMLKit.Element;7980/*81* @author jrose, ksrini82*/83public class ClassReader {8485private static final CommandLineParser CLP = new CommandLineParser(""86+ "-source: +> = \n"87+ "-dest: +> = \n"88+ "-encoding: +> = \n"89+ "-jcov $ \n -nojcov !-jcov \n"90+ "-verbose $ \n -noverbose !-verbose \n"91+ "-keepPath $ \n -nokeepPath !-keepPath \n"92+ "-keepCP $ \n -nokeepCP !-keepCP \n"93+ "-keepOrder $ \n -nokeepOrder !-keepOrder \n"94+ "-continue $ \n -nocontinue !-continue \n"95+ "-@ >-@ . \n"96+ "- +? \n"97+ "\n");9899100// Protected state for representing the class file.101protected Element cfile; // <ClassFile ...>102protected Element cpool; // <ConstantPool ...>103protected Element klass; // <Class ...>104protected List<String> thePool; // stringified flattened Constant Pool105106public static void main(String[] ava) throws IOException {107ArrayList<String> av = new ArrayList<>(Arrays.asList(ava));108HashMap<String, String> props = new HashMap<>();109props.put("-encoding:", "UTF8"); // default110props.put("-keepOrder", null); // CLI default111props.put("-pretty", "1"); // CLI default112props.put("-continue", "1"); // CLI default113CLP.parse(av, props);114//System.out.println(props+" ++ "+av);115File source = asFile(props.get("-source:"));116File dest = asFile(props.get("-dest:"));117String encoding = props.get("-encoding:");118boolean contError = props.containsKey("-continue");119ClassReader options = new ClassReader();120options.copyOptionsFrom(props);121/*122if (dest == null && av.size() > 1) {123dest = File.createTempFile("TestOut", ".dir", new File("."));124dest.delete();125if (!dest.mkdir())126throw new RuntimeException("Cannot create "+dest);127System.out.println("Writing results to "+dest);128}129*/130if (av.isEmpty()) {131av.add(""); //to enter this loop132}133boolean readList = false;134for (String a : av) {135if (readList) {136readList = false;137InputStream fin;138if (a.equals("-")) {139fin = System.in;140} else {141fin = new FileInputStream(a);142}143144BufferedReader files = makeReader(fin, encoding);145for (String file; (file = files.readLine()) != null;) {146doFile(file, source, dest, options, encoding, contError);147}148if (fin != System.in) {149fin.close();150}151} else if (a.equals("-@")) {152readList = true;153} else if (a.startsWith("-")) {154throw new RuntimeException("Bad flag argument: " + a);155} else if (source.getName().endsWith(".jar")) {156doJar(a, source, dest, options, encoding, contError);157} else {158doFile(a, source, dest, options, encoding, contError);159}160}161}162163private static File asFile(String str) {164return (str == null) ? null : new File(str);165}166167private static void doFile(String a,168File source, File dest,169ClassReader options, String encoding,170boolean contError) throws IOException {171if (!contError) {172doFile(a, source, dest, options, encoding);173} else {174try {175doFile(a, source, dest, options, encoding);176} catch (Exception ee) {177System.out.println("Error processing " + source + ": " + ee);178ee.printStackTrace();179}180}181}182183private static void doJar(String a, File source, File dest,184ClassReader options, String encoding,185Boolean contError) throws IOException {186try {187JarFile jf = new JarFile(source);188for (JarEntry je : Collections.list(jf.entries())) {189String name = je.getName();190if (!name.endsWith(".class")) {191continue;192}193try {194doStream(name, jf.getInputStream(je), dest, options, encoding);195} catch (Exception e) {196if (contError) {197System.out.println("Error processing " + source + ": " + e);198e.printStackTrace();199continue;200}201}202}203} catch (IOException ioe) {204throw ioe;205}206}207208private static void doStream(String a, InputStream in, File dest,209ClassReader options, String encoding) throws IOException {210211File f = new File(a);212ClassReader cr = new ClassReader(options);213Element e;214if (options.verbose) {215System.out.println("Reading " + f);216}217e = cr.readFrom(in);218219OutputStream out;220if (dest == null) {221out = System.out;222} else {223File outf = new File(dest, f.isAbsolute() ? f.getName() : f.getPath());224String outName = outf.getName();225File outSubdir = outf.getParentFile();226outSubdir.mkdirs();227int extPos = outName.lastIndexOf('.');228if (extPos > 0) {229outf = new File(outSubdir, outName.substring(0, extPos) + ".xml");230}231out = new FileOutputStream(outf);232}233234Writer outw = makeWriter(out, encoding);235if (options.pretty || !options.keepOrder) {236e.writePrettyTo(outw);237} else {238e.writeTo(outw);239}240if (out == System.out) {241outw.write("\n");242outw.flush();243} else {244outw.close();245}246}247248private static void doFile(String a,249File source, File dest,250ClassReader options, String encoding) throws IOException {251File inf = new File(source, a);252if (dest != null && options.verbose) {253System.out.println("Reading " + inf);254}255256BufferedInputStream in = new BufferedInputStream(new FileInputStream(inf));257258doStream(a, in, dest, options, encoding);259260}261262public static BufferedReader makeReader(InputStream in,263String encoding) throws IOException {264Reader inw;265in = new BufferedInputStream(in); // add buffering266if (encoding == null) {267inw = new InputStreamReader(in);268} else {269inw = new InputStreamReader(in, encoding);270}271return new BufferedReader(inw); // add buffering272}273274public static Writer makeWriter(OutputStream out,275String encoding) throws IOException {276Writer outw;277if (encoding == null) {278outw = new OutputStreamWriter(out);279} else {280outw = new OutputStreamWriter(out, encoding);281}282return new BufferedWriter(outw); // add buffering283}284285public Element result() {286return cfile;287}288289protected InputStream in;290protected ByteArrayOutputStream buf = new ByteArrayOutputStream(1024);291// input options292public boolean pretty = false;293public boolean verbose = false;294public boolean keepPath = false;295public boolean keepCP = false;296public boolean keepBytes = false;297public boolean parseBytes = true;298public boolean resolveRefs = true;299public boolean keepOrder = true;300public boolean keepSizes = false;301302public ClassReader() {303cfile = new Element("ClassFile");304}305306public ClassReader(ClassReader options) {307this();308copyOptionsFrom(options);309}310311public void copyOptionsFrom(ClassReader options) {312pretty = options.pretty;313verbose = options.verbose;314keepPath = options.keepPath;315keepCP = options.keepCP;316keepOrder = options.keepOrder;317}318319public void copyOptionsFrom(Map<String, String> options) {320if (options.containsKey("-pretty")) {321pretty = (options.get("-pretty") != null);322}323if (options.containsKey("-verbose")) {324verbose = (options.get("-verbose") != null);325}326if (options.containsKey("-keepPath")) {327keepPath = (options.get("-keepPath") != null);328}329if (options.containsKey("-keepCP")) {330keepCP = (options.get("-keepCP") != null);331}332if (options.containsKey("-keepOrder")) {333keepOrder = (options.get("-keepOrder") != null);334}335}336337protected String getCpString(int i) {338return thePool.get(i);339}340341public Element readFrom(InputStream in) throws IOException {342try {343this.in = in;344ClassFile c = ClassFile.read(in);345// read the file header346if (c.magic != 0xCAFEBABE) {347throw new RuntimeException("bad magic number " +348Integer.toHexString(c.magic));349}350cfile.setAttr("magic", "" + c.magic);351int minver = c.minor_version;352int majver = c.major_version;353cfile.setAttr("minver", "" + minver);354cfile.setAttr("majver", "" + majver);355readCP(c);356readClass(c);357return result();358} catch (InvalidDescriptor | ConstantPoolException ex) {359throw new IOException("Fatal error", ex);360}361}362363public Element readFrom(File file) throws IOException {364try (InputStream strm = new FileInputStream(file)) {365Element e = readFrom(new BufferedInputStream(strm));366if (keepPath) {367e.setAttr("path", file.toString());368}369return e;370}371}372373private void readClass(ClassFile c) throws IOException,374ConstantPoolException,375InvalidDescriptor {376klass = new Element("Class");377cfile.add(klass);378String thisk = c.getName();379380klass.setAttr("name", thisk);381382AccessFlags af = new AccessFlags(c.access_flags.flags);383klass.setAttr("flags", flagString(af, klass));384if (!"java/lang/Object".equals(thisk)) {385klass.setAttr("super", c.getSuperclassName());386}387for (int i : c.interfaces) {388klass.add(new Element("Interface", "name", getCpString(i)));389}390readFields(c, klass);391readMethods(c, klass);392readAttributesFor(c, c.attributes, klass);393klass.trimToSize();394}395396private void readFields(ClassFile c, Element klass) throws IOException {397int len = c.fields.length;398Element fields = new Element(len);399for (Field f : c.fields) {400Element field = new Element("Field");401field.setAttr("name", getCpString(f.name_index));402field.setAttr("type", getCpString(f.descriptor.index));403field.setAttr("flags", flagString(f.access_flags.flags, field));404readAttributesFor(c, f.attributes, field);405406field.trimToSize();407fields.add(field);408}409if (!keepOrder) {410fields.sort();411}412klass.addAll(fields);413}414415416private void readMethods(ClassFile c, Element klass) throws IOException {417int len = c.methods.length;418Element methods = new Element(len);419for (Method m : c.methods) {420Element member = new Element("Method");421member.setAttr("name", getCpString(m.name_index));422member.setAttr("type", getCpString(m.descriptor.index));423member.setAttr("flags", flagString(m.access_flags.flags, member));424readAttributesFor(c, m.attributes, member);425426member.trimToSize();427methods.add(member);428}429if (!keepOrder) {430methods.sort();431}432klass.addAll(methods);433}434435private AccessFlags.Kind getKind(Element e) {436switch(e.getName()) {437case "Class":438return AccessFlags.Kind.Class;439case "InnerClass":440return AccessFlags.Kind.InnerClass;441case "Field":442return AccessFlags.Kind.Field ;443case "Method":444return AccessFlags.Kind.Method;445default: throw new RuntimeException("should not reach here");446}447}448449protected String flagString(int flags, Element holder) {450return flagString(new AccessFlags(flags), holder);451}452protected String flagString(AccessFlags af, Element holder) {453return flagString(af, holder.getName());454}455protected String flagString(int flags, String kind) {456return flagString(new AccessFlags(flags), kind);457}458protected String flagString(AccessFlags af, String kind) {459Set<String> mods = null;460switch (kind) {461case "Class":462mods = af.getClassFlags();463break;464case "InnerClass":465mods = af.getInnerClassFlags();466break;467case "Field":468mods = af.getFieldFlags();469break;470case "Method":471mods = af.getMethodFlags();472break;473default:474throw new RuntimeException("should not reach here");475}476StringBuilder sb = new StringBuilder();477for (String x : mods) {478sb.append(x.substring(x.indexOf('_') + 1).toLowerCase()).append(" ");479}480return sb.toString().trim();481}482483484protected void readAttributesFor(ClassFile c, Attributes attrs, Element x) {485Element container = new Element();486AttributeVisitor av = new AttributeVisitor(this, c);487for (Attribute a : attrs) {488av.visit(a, container);489}490if (!keepOrder) {491container.sort();492}493x.addAll(container);494}495496private int fileSize = 0;497private HashMap<String, int[]> attrSizes = new HashMap<>();498499private void attachTo(Element x, Object aval0) {500if (aval0 == null) {501return;502}503if (!(aval0 instanceof Element)) {504x.add(aval0);505return;506}507Element aval = (Element) aval0;508if (!aval.isAnonymous()) {509x.add(aval);510return;511}512for (int imax = aval.attrSize(), i = 0; i < imax; i++) {513//%%514attachAttrTo(x, aval.getAttrName(i), aval.getAttr(i));515}516x.addAll(aval);517}518519private void attachAttrTo(Element x, String aname, String aval) {520String aval0 = x.getAttr(aname);521if (aval0 != null) {522aval = aval0 + " " + aval;523}524x.setAttr(aname, aval);525}526527private void readCP(ClassFile c) throws IOException {528cpool = new Element("ConstantPool", c.constant_pool.size());529ConstantPoolVisitor cpv = new ConstantPoolVisitor(cpool, c,530c.constant_pool.size());531for (int i = 1 ; i < c.constant_pool.size() ; i++) {532try {533cpv.visit(c.constant_pool.get(i), i);534} catch (InvalidIndex ex) {535// can happen periodically when accessing doubles etc. ignore it536// ex.printStackTrace();537}538}539thePool = cpv.getPoolList();540if (verbose) {541for (int i = 0; i < thePool.size(); i++) {542System.out.println("[" + i + "]: " + thePool.get(i));543}544}545if (keepCP) {546cfile.add(cpool);547}548}549}550551class ConstantPoolVisitor implements ConstantPool.Visitor<String, Integer> {552final List<String> slist;553final Element xpool;554final ClassFile cf;555final ConstantPool cfpool;556final List<String> bsmlist;557558559public ConstantPoolVisitor(Element xpool, ClassFile cf, int size) {560slist = new ArrayList<>(size);561for (int i = 0 ; i < size; i++) {562slist.add(null);563}564this.xpool = xpool;565this.cf = cf;566this.cfpool = cf.constant_pool;567bsmlist = readBSM();568}569570public List<String> getPoolList() {571return Collections.unmodifiableList(slist);572}573574public List<String> getBSMList() {575return Collections.unmodifiableList(bsmlist);576}577578public String visit(CPInfo c, int index) {579return c.accept(this, index);580}581582private List<String> readBSM() {583BootstrapMethods_attribute bsmAttr =584(BootstrapMethods_attribute) cf.getAttribute(Attribute.BootstrapMethods);585if (bsmAttr != null) {586List<String> out =587new ArrayList<>(bsmAttr.bootstrap_method_specifiers.length);588for (BootstrapMethods_attribute.BootstrapMethodSpecifier bsms :589bsmAttr.bootstrap_method_specifiers) {590int index = bsms.bootstrap_method_ref;591try {592String value = slist.get(index);593String bsmStr = value;594if (value == null) {595value = visit(cfpool.get(index), index);596slist.set(index, value);597}598bsmStr = value;599for (int idx : bsms.bootstrap_arguments) {600value = slist.get(idx);601if (value == null) {602value = visit(cfpool.get(idx), idx);603slist.set(idx, value);604}605bsmStr = bsmStr.concat("," + value);606}607out.add(bsmStr);608} catch (InvalidIndex ex) {609ex.printStackTrace();610}611}612return out;613}614return new ArrayList<>(0);615}616617@Override618public String visitClass(CONSTANT_Class_info c, Integer p) {619String value = slist.get(p);620if (value == null) {621try {622value = visit(cfpool.get(c.name_index), c.name_index);623slist.set(p, value);624xpool.add(new Element("CONSTANT_Class",625new String[]{"id", p.toString()},626value));627} catch (ConstantPoolException ex) {628ex.printStackTrace();629}630}631return value;632}633634@Override635public String visitDouble(CONSTANT_Double_info c, Integer p) {636String value = slist.get(p);637if (value == null) {638value = Double.toString(c.value);639slist.set(p, value);640xpool.add(new Element("CONSTANT_Double",641new String[]{"id", p.toString()},642value));643}644return value;645}646647@Override648public String visitFieldref(CONSTANT_Fieldref_info c, Integer p) {649String value = slist.get(p);650if (value == null) {651try {652value = visit(cfpool.get(c.class_index), c.class_index);653value = value.concat(" " + visit(cfpool.get(c.name_and_type_index),654c.name_and_type_index));655slist.set(p, value);656xpool.add(new Element("CONSTANT_Fieldref",657new String[]{"id", p.toString()},658value));659} catch (ConstantPoolException ex) {660ex.printStackTrace();661}662}663return value;664}665666@Override667public String visitFloat(CONSTANT_Float_info c, Integer p) {668String value = slist.get(p);669if (value == null) {670value = Float.toString(c.value);671slist.set(p, value);672xpool.add(new Element("CONSTANT_Float",673new String[]{"id", p.toString()},674value));675}676return value;677}678679@Override680public String visitInteger(CONSTANT_Integer_info cnstnt, Integer p) {681String value = slist.get(p);682if (value == null) {683value = Integer.toString(cnstnt.value);684slist.set(p, value);685xpool.add(new Element("CONSTANT_Integer",686new String[]{"id", p.toString()},687value));688}689return value;690}691692@Override693public String visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info c,694Integer p) {695String value = slist.get(p);696if (value == null) {697try {698value = visit(cfpool.get(c.class_index), c.class_index);699value = value.concat(" " +700visit(cfpool.get(c.name_and_type_index),701c.name_and_type_index));702slist.set(p, value);703xpool.add(new Element("CONSTANT_InterfaceMethodref",704new String[]{"id", p.toString()},705value));706707} catch (ConstantPoolException ex) {708ex.printStackTrace();709}710}711return value;712}713714@Override715public String visitInvokeDynamic(CONSTANT_InvokeDynamic_info c, Integer p) {716String value = slist.get(p);717if (value == null) {718try {719value = bsmlist.get(c.bootstrap_method_attr_index) + " "720+ visit(cfpool.get(c.name_and_type_index), c.name_and_type_index);721slist.set(p, value);722xpool.add(new Element("CONSTANT_InvokeDynamic",723new String[]{"id", p.toString()},724value));725726} catch (ConstantPoolException ex) {727ex.printStackTrace();728}729}730return value;731}732733@Override734public String visitLong(CONSTANT_Long_info c, Integer p) {735String value = slist.get(p);736if (value == null) {737value = Long.toString(c.value);738slist.set(p, value);739xpool.add(new Element("CONSTANT_Long",740new String[]{"id", p.toString()},741value));742}743return value;744}745746@Override747public String visitNameAndType(CONSTANT_NameAndType_info c, Integer p) {748String value = slist.get(p);749if (value == null) {750try {751value = visit(cfpool.get(c.name_index), c.name_index);752value = value.concat(" " +753visit(cfpool.get(c.type_index), c.type_index));754slist.set(p, value);755xpool.add(new Element("CONSTANT_NameAndType",756new String[]{"id", p.toString()},757value));758} catch (InvalidIndex ex) {759ex.printStackTrace();760}761}762return value;763}764765@Override766public String visitMethodref(CONSTANT_Methodref_info c, Integer p) {767String value = slist.get(p);768if (value == null) {769try {770value = visit(cfpool.get(c.class_index), c.class_index);771value = value.concat(" " +772visit(cfpool.get(c.name_and_type_index),773c.name_and_type_index));774slist.set(p, value);775xpool.add(new Element("CONSTANT_Methodref",776new String[]{"id", p.toString()},777value));778779} catch (ConstantPoolException ex) {780ex.printStackTrace();781}782}783return value;784}785786@Override787public String visitMethodHandle(CONSTANT_MethodHandle_info c, Integer p) {788String value = slist.get(p);789if (value == null) {790try {791value = c.reference_kind.name();792value = value.concat(" "793+ visit(cfpool.get(c.reference_index), c.reference_index));794slist.set(p, value);795xpool.add(new Element("CONSTANT_MethodHandle",796new String[]{"id", p.toString()},797value));798799} catch (ConstantPoolException ex) {800ex.printStackTrace();801}802}803return value;804}805806@Override807public String visitMethodType(CONSTANT_MethodType_info c, Integer p) {808String value = slist.get(p);809if (value == null) {810try {811value = visit(cfpool.get(c.descriptor_index), c.descriptor_index);812slist.set(p, value);813xpool.add(new Element("CONSTANT_MethodType",814new String[]{"id", p.toString()},815value));816} catch (ConstantPoolException ex) {817ex.printStackTrace();818}819}820return value;821}822823@Override824public String visitString(CONSTANT_String_info c, Integer p) {825try {826827String value = slist.get(p);828if (value == null) {829value = c.getString();830slist.set(p, value);831xpool.add(new Element("CONSTANT_String",832new String[]{"id", p.toString()},833value));834}835return value;836} catch (ConstantPoolException ex) {837throw new RuntimeException("Fatal error", ex);838}839}840841@Override842public String visitUtf8(CONSTANT_Utf8_info cnstnt, Integer p) {843String value = slist.get(p);844if (value == null) {845value = cnstnt.value;846slist.set(p, value);847xpool.add(new Element("CONSTANT_Utf8",848new String[]{"id", p.toString()},849value));850}851return value;852853}854}855856857class AttributeVisitor implements Attribute.Visitor<Element, Element> {858final ClassFile cf;859final ClassReader x;860final AnnotationsElementVisitor aev;861final InstructionVisitor iv;862863public AttributeVisitor(ClassReader x, ClassFile cf) {864this.x = x;865this.cf = cf;866iv = new InstructionVisitor(x, cf);867aev = new AnnotationsElementVisitor(x, cf);868}869870public void visit(Attribute a, Element parent) {871a.accept(this, parent);872}873874@Override875public Element visitBootstrapMethods(BootstrapMethods_attribute bm, Element p) {876Element e = new Element(x.getCpString(bm.attribute_name_index));877for (BootstrapMethods_attribute.BootstrapMethodSpecifier bsm : bm.bootstrap_method_specifiers) {878Element be = new Element("BootstrapMethodSpecifier");879be.setAttr("ref", x.getCpString(bsm.bootstrap_method_ref));880if (bsm.bootstrap_arguments.length > 0) {881Element bme = new Element("MethodArguments");882for (int index : bsm.bootstrap_arguments) {883bme.add(x.getCpString(index));884}885bme.trimToSize();886be.add(bme);887}888be.trimToSize();889e.add(be);890}891e.trimToSize();892if (!x.keepOrder) {893e.sort();894}895p.add(e);896return null;897}898899@Override900public Element visitDefault(DefaultAttribute da, Element p) {901Element e = new Element(x.getCpString(da.attribute_name_index));902StringBuilder sb = new StringBuilder();903for (byte x : da.info) {904sb.append("0x").append(Integer.toHexString(x)).append(" ");905}906e.setAttr("bytes", sb.toString().trim());907e.trimToSize();908p.add(e);909return null;910}911912@Override913public Element visitAnnotationDefault(AnnotationDefault_attribute ad, Element p) {914Element e = new Element(x.getCpString(ad.attribute_name_index));915e.setAttr("tag", "" + ad.default_value.tag);916Element child = aev.visit(ad.default_value, e);917if (child != null) {918e.add(child);919}920e.trimToSize();921p.add(e);922return null;923}924925@Override926public Element visitCharacterRangeTable(CharacterRangeTable_attribute crt,927Element p) {928Element e = new Element(x.getCpString(crt.attribute_name_index));929for (CharacterRangeTable_attribute.Entry ce : crt.character_range_table) {930e.setAttr("start_pc", "" + ce.start_pc);931e.setAttr("end_pc", "" + ce.end_pc);932e.setAttr("range_start", "" + ce.character_range_start);933e.setAttr("range_end", "" + ce.character_range_end);934e.setAttr("flags", x.flagString(ce.flags, "Method"));935}936e.trimToSize();937p.add(e);938return null;939}940941private Element instructions(Element code, Code_attribute c) {942Element ielement = new Element("Instructions");943for (Instruction ins : c.getInstructions()) {944ielement.add(iv.visit(ins));945}946ielement.trimToSize();947return ielement;948}949950@Override951public Element visitCode(Code_attribute c, Element p) {952Element e = null;953954e = new Element(x.getCpString(c.attribute_name_index),955"stack", "" + c.max_stack,956"local", "" + c.max_locals);957958e.add(instructions(e, c));959960for (Code_attribute.Exception_data edata : c.exception_table) {961e.add(new Element("Handler",962"start", "" + edata.start_pc,963"end", "" + edata.end_pc,964"catch", "" + edata.handler_pc,965"class", x.getCpString(edata.catch_type)));966967}968this.x.readAttributesFor(cf, c.attributes, e);969e.trimToSize();970p.add(e);971return null;972}973974@Override975public Element visitCompilationID(CompilationID_attribute cid, Element p) {976Element e = new Element(x.getCpString(cid.attribute_name_index),977x.getCpString(cid.compilationID_index));978p.add(e);979return null;980}981982@Override983public Element visitConstantValue(ConstantValue_attribute cv, Element p) {984Element e = new Element(x.getCpString(cv.attribute_name_index));985e.add(x.getCpString(cv.constantvalue_index));986p.add(e);987return null;988}989990@Override991public Element visitDeprecated(Deprecated_attribute d, Element p) {992Element e = new Element(x.getCpString(d.attribute_name_index));993p.add(e);994return null;995}996997@Override998public Element visitEnclosingMethod(EnclosingMethod_attribute em, Element p) {999Element e = new Element(x.getCpString(em.attribute_name_index));1000e.setAttr("class", x.getCpString(em.class_index));1001e.setAttr("desc", x.getCpString(em.method_index));1002e.trimToSize();1003p.add(e);1004return null;1005}10061007@Override1008public Element visitExceptions(Exceptions_attribute e, Element p) {1009Element ee = new Element(x.getCpString(e.attribute_name_index));1010for (int idx : e.exception_index_table) {1011Element n = new Element("Item");1012n.setAttr("class", x.getCpString(idx));1013ee.add(n);1014}1015ee.trimToSize();1016p.add(ee);1017return null;1018}10191020@Override1021public Element visitInnerClasses(InnerClasses_attribute ic, Element p) {1022for (Info info : ic.classes) {1023Element e = new Element(x.getCpString(ic.attribute_name_index));1024e.setAttr("class", x.getCpString(info.inner_class_info_index));1025e.setAttr("outer", x.getCpString(info.outer_class_info_index));1026e.setAttr("name", x.getCpString(info.inner_name_index));1027e.setAttr("flags", x.flagString(info.inner_class_access_flags,1028"InnerClass"));1029e.trimToSize();1030p.add(e);1031}1032return null;1033}10341035@Override1036public Element visitLineNumberTable(LineNumberTable_attribute lnt, Element p) {1037String name = x.getCpString(lnt.attribute_name_index);1038for (LineNumberTable_attribute.Entry e : lnt.line_number_table) {1039Element l = new Element(name);1040l.setAttr("bci", "" + e.start_pc);1041l.setAttr("line", "" + e.line_number);1042l.trimToSize();1043p.add(l);1044}1045return null; // already added to parent1046}10471048@Override1049public Element visitLocalVariableTable(LocalVariableTable_attribute lvt,1050Element p) {1051String name = x.getCpString(lvt.attribute_name_index);1052for (LocalVariableTable_attribute.Entry e : lvt.local_variable_table) {1053Element l = new Element(name);1054l.setAttr("bci", "" + e.start_pc);1055l.setAttr("span", "" + e.length);1056l.setAttr("name", x.getCpString(e.name_index));1057l.setAttr("type", x.getCpString(e.descriptor_index));1058l.setAttr("slot", "" + e.index);1059l.trimToSize();1060p.add(l);1061}1062return null; // already added to parent1063}10641065@Override1066public Element visitLocalVariableTypeTable(LocalVariableTypeTable_attribute lvtt,1067Element p) {1068String name = x.getCpString(lvtt.attribute_name_index);1069for (LocalVariableTypeTable_attribute.Entry e : lvtt.local_variable_table) {1070Element l = new Element(name);1071l.setAttr("bci", "" + e.start_pc);1072l.setAttr("span", "" + e.length);1073l.setAttr("name", x.getCpString(e.name_index));1074l.setAttr("type", x.getCpString(e.signature_index));1075l.setAttr("slot", "" + e.index);1076l.trimToSize();1077p.add(l);1078}1079return null; // already added to parent1080}10811082@Override1083public Element visitMethodParameters(MethodParameters_attribute mp, Element p) {1084String name = x.getCpString(mp.attribute_name_index);1085for (MethodParameters_attribute.Entry e : mp.method_parameter_table) {1086Element l = new Element(name);1087l.setAttr("name", x.getCpString(e.name_index));1088l.setAttr("flag", "" + e.flags);1089l.trimToSize();1090p.add(l);1091}1092return null; // already added to parent1093}1094private void parseAnnotation(Annotation anno, Element p) {1095Element ea = new Element("Annotation");1096ea.setAttr("name", "" + x.getCpString(anno.type_index));1097for (Annotation.element_value_pair evp : anno.element_value_pairs) {1098Element evpe = new Element("Element");1099evpe.setAttr("tag", "" + evp.value.tag);1100evpe.setAttr("value", x.getCpString(evp.element_name_index));1101Element child = aev.visit(evp.value, evpe);1102if (child != null) {1103evpe.add(child);1104}1105ea.add(evpe);1106}1107ea.trimToSize();1108p.add(ea);1109}11101111private void parseAnnotations(Annotation[] ra, Element p) {1112for (Annotation anno : ra) {1113parseAnnotation(anno, p);1114}1115}11161117@Override1118public Element visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute rva,1119Element p) {1120Element e = new Element(x.getCpString(rva.attribute_name_index));1121parseAnnotations(rva.annotations, e);1122e.trimToSize();1123p.add(e);1124return null;1125}11261127@Override1128public Element visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute ria,1129Element p) {1130Element e = new Element(x.getCpString(ria.attribute_name_index));1131parseAnnotations(ria.annotations, e);1132e.trimToSize();1133p.add(e);1134return null;1135}11361137@Override1138public Element visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute rvpa,1139Element p) {1140Element e = new Element(x.getCpString(rvpa.attribute_name_index));1141for (Annotation[] pa : rvpa.parameter_annotations) {1142parseAnnotations(pa, e);1143}1144p.add(e);1145return null;1146}11471148@Override1149public Element visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute ripa,1150Element p) {1151Element e = new Element(x.getCpString(ripa.attribute_name_index));1152for (Annotation[] pa : ripa.parameter_annotations) {1153parseAnnotations(pa, e);1154}1155p.add(e);1156return null;1157}11581159private void parsePosition(Position ap, Element p) {1160Element te = new Element();1161switch (ap.type) {1162case CLASS_TYPE_PARAMETER: // 0x001163te.setName("CLASS_TYPE_PARAMETER");1164te.setAttr("idx", "" + ap.parameter_index);1165break;1166case METHOD_TYPE_PARAMETER: // 0x011167te.setName("METHOD_TYPE_PARAMETER");1168te.setAttr("idx", "" + ap.parameter_index);1169break;1170case CLASS_EXTENDS: // 0x101171te.setName("CLASS_EXTENDS");1172te.setAttr("idx", "" + ap.type_index);1173break;1174case CLASS_TYPE_PARAMETER_BOUND: // 0x111175te.setName("CLASS_TYPE_PARAMETER_BOUND");1176te.setAttr("idx1", "" + ap.parameter_index);1177te.setAttr("idx2", "" + ap.bound_index);1178break;1179case METHOD_TYPE_PARAMETER_BOUND: // 0x121180te.setName("METHOD_TYPE_PARAMETER_BOUND");1181te.setAttr("idx1", "" + ap.parameter_index);1182te.setAttr("idx2", "" + ap.bound_index);1183break;1184case FIELD: // 0x131185te.setName("FIELD");1186break;1187case METHOD_RETURN: // 0x141188te.setName("METHOD_RETURN");1189break;1190case METHOD_RECEIVER: // 0x151191te.setName("METHOD_RECEIVER");1192break;1193case METHOD_FORMAL_PARAMETER: // 0x161194te.setName("METHOD_FORMAL_PARAMETER");1195te.setAttr("idx", "" + ap.parameter_index);1196break;1197case THROWS: // 0x171198te.setName("THROWS");1199te.setAttr("idx", "" + ap.type_index);1200break;1201case LOCAL_VARIABLE: // 0x401202te.setName("LOCAL_VARIABLE");1203for (int i = 0; i < ap.lvarIndex.length; i++) {1204te.setAttr("lvar_idx_" + i, "" + ap.lvarIndex[i]);1205te.setAttr("lvar_len_" + i, "" + ap.lvarLength[i]);1206te.setAttr("lvar_off_" + i, "" + ap.lvarOffset[i]);1207}1208break;1209case RESOURCE_VARIABLE: // 0x411210te.setName("RESOURCE_VARIABLE");1211for (int i = 0; i < ap.lvarIndex.length ; i++) {1212te.setAttr("lvar_idx_" + i, "" + ap.lvarIndex[i]);1213te.setAttr("lvar_len_" + i, "" + ap.lvarLength[i]);1214te.setAttr("lvar_off_" + i, "" + ap.lvarOffset[i]);1215}1216break;1217case EXCEPTION_PARAMETER: // 0x421218te.setName("EXCEPTION_PARAMETER");1219te.setAttr("idx", "" + ap.exception_index);1220break;1221case INSTANCEOF: // 0x431222te.setName("INSTANCE_OF");1223te.setAttr("off", "" + ap.offset);1224break;1225case NEW: // 0x441226te.setName("NEW");1227te.setAttr("off", "" + ap.offset);1228break;1229case CONSTRUCTOR_REFERENCE: // 0x451230te.setName("CONSTRUCTOR_REFERENCE_RECEIVER");1231te.setAttr("off", "" + ap.offset);1232break;1233case METHOD_REFERENCE: // 0x461234te.setName("METHOD_REFERENCE_RECEIVER");1235te.setAttr("off", "" + ap.offset);1236break;1237case CAST: // 0x471238te.setName("CAST");1239te.setAttr("off", "" + ap.offset);1240te.setAttr("idx", "" + ap.type_index);1241break;1242case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: // 0x481243te.setName("CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT");1244te.setAttr("off", "" + ap.offset);1245te.setAttr("idx", "" + ap.type_index);1246break;1247case METHOD_INVOCATION_TYPE_ARGUMENT: // 0x491248te.setName("METHOD_INVOCATION_TYPE_ARGUMENT");1249te.setAttr("off", "" + ap.offset);1250te.setAttr("idx", "" + ap.type_index);1251break;1252case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: // 0x4A1253te.setName("CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT");1254te.setAttr("off", "" + ap.offset);1255te.setAttr("idx", "" + ap.type_index);1256break;1257case METHOD_REFERENCE_TYPE_ARGUMENT: // 0x4B1258te.setName("METHOD_REFERENCE_TYPE_ARGUMENT");1259te.setAttr("off", "" + ap.offset);1260te.setAttr("idx", "" + ap.type_index);1261break;1262default:1263throw new RuntimeException("not implemented");1264}1265te.trimToSize();1266p.add(te);1267}1268private void parseTypeAnnotations(TypeAnnotation pa, Element p) {1269Element pta = new Element("RuntimeVisibleTypeAnnotation");1270p.add(pta);1271Position pos = pa.position;1272parsePosition(pos, pta);1273parseAnnotation(pa.annotation, pta);1274}12751276@Override1277public Element visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute rvta, Element p) {1278Element e = new Element(x.getCpString(rvta.attribute_name_index));1279for (TypeAnnotation pa : rvta.annotations) {1280parseTypeAnnotations(pa, e);1281}1282e.sort();1283p.add(e);1284return null;1285}12861287@Override1288public Element visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute rita, Element p) {1289Element e = new Element(x.getCpString(rita.attribute_name_index));1290for (TypeAnnotation pa : rita.annotations) {1291parseTypeAnnotations(pa, e);1292}1293e.sort();1294p.add(e);1295return null;1296}12971298@Override1299public Element visitSignature(Signature_attribute s, Element p) {1300String aname = x.getCpString(s.attribute_name_index);1301String sname = x.getCpString(s.signature_index);1302Element se = new Element(aname);1303se.add(sname);1304se.trimToSize();1305p.add(se);1306return null;1307}13081309@Override1310public Element visitSourceDebugExtension(SourceDebugExtension_attribute sde,1311Element p) {1312String aname = x.getCpString(sde.attribute_name_index);1313Element se = new Element(aname);1314se.setAttr("val", sde.getValue());1315se.trimToSize();1316p.add(se);1317return null;1318}13191320@Override1321public Element visitSourceFile(SourceFile_attribute sf, Element p) {1322String aname = x.getCpString(sf.attribute_name_index);1323String sname = x.getCpString(sf.sourcefile_index);1324Element se = new Element(aname);1325se.add(sname);1326se.trimToSize();1327p.add(se);1328return null;1329}13301331@Override1332public Element visitSourceID(SourceID_attribute sid, Element p) {1333Element e = new Element(x.getCpString(sid.attribute_name_index));1334e.add(x.getCpString(sid.sourceID_index));1335e.trimToSize();1336p.add(e);1337return null;1338}13391340@Override1341public Element visitStackMap(StackMap_attribute sm, Element p) {1342throw new UnsupportedOperationException("Not supported yet.");1343}13441345@Override1346public Element visitStackMapTable(StackMapTable_attribute smt, Element p) {1347Element stackmap = new Element(x.getCpString(smt.attribute_name_index));1348for (StackMapTable_attribute.stack_map_frame f : smt.entries) {1349StackMapVisitor smv = new StackMapVisitor(x, cf, stackmap);1350stackmap.add(smv.visit(f));1351}1352stackmap.trimToSize();1353p.add(stackmap);1354return null;1355}13561357@Override1358public Element visitSynthetic(Synthetic_attribute s, Element p) {1359Element e = new Element(x.getCpString(s.attribute_name_index));1360e.trimToSize();1361p.add(e);1362return null;1363}1364}13651366class StackMapVisitor implements StackMapTable_attribute.stack_map_frame.Visitor<Element, Void> {13671368final ClassFile cf;1369final ClassReader x;1370final Element parent;13711372public StackMapVisitor(ClassReader x, ClassFile cf, Element parent) {1373this.x = x;1374this.cf = cf;1375this.parent = parent;1376}13771378public Element visit(StackMapTable_attribute.stack_map_frame frame) {1379return frame.accept(this, null);1380}13811382@Override1383public Element visit_same_frame(same_frame sm_frm, Void p) {1384Element e = new Element("SameFrame");1385e.setAttr("tag", "" + sm_frm.frame_type);1386return e;1387}13881389@Override1390public Element visit_same_locals_1_stack_item_frame(same_locals_1_stack_item_frame s, Void p) {1391Element e = new Element("SameLocals1StackItemFrame");1392e.setAttr("tag", "" + s.frame_type);1393e.addAll(getVerificationTypeInfo("Stack", s.stack));1394e.trimToSize();1395return e;1396}13971398@Override1399public Element visit_same_locals_1_stack_item_frame_extended(same_locals_1_stack_item_frame_extended s, Void p) {1400Element e = new Element("SameLocals1StackItemFrameExtended");1401e.setAttr("tag", "" + s.frame_type);1402e.addAll(getVerificationTypeInfo("Stack", s.stack));1403e.trimToSize();1404return e;1405}14061407@Override1408public Element visit_chop_frame(chop_frame c, Void p) {1409Element e = new Element("Chop" + (251 - c.frame_type));1410e.setAttr("tag", "" + c.frame_type);1411e.setAttr("offset", "" + c.offset_delta);1412return e;1413}14141415@Override1416public Element visit_same_frame_extended(same_frame_extended s, Void p) {1417Element e = new Element("SameFrameExtended");1418e.setAttr("tag", "" + s.frame_type);1419e.setAttr("offset", "" + s.offset_delta);1420return e;1421}14221423@Override1424public Element visit_append_frame(append_frame a, Void p) {1425Element e = new Element("AppendFrame" + (a.frame_type - 251));1426e.setAttr("tag", "" + a.frame_type);1427e.addAll(getVerificationTypeInfo("Local", a.locals));1428e.trimToSize();1429return e;1430}14311432@Override1433public Element visit_full_frame(full_frame fl_frm, Void p) {1434Element e = new Element("FullFrame");1435e.setAttr("tag", "" + fl_frm.frame_type);1436e.addAll(getVerificationTypeInfo("Local", fl_frm.locals));1437e.trimToSize();1438return e;1439}14401441private Element getVerificationTypeInfo(String kind,1442StackMapTable_attribute.verification_type_info velems[]) {1443Element container = new Element(velems.length);1444for (StackMapTable_attribute.verification_type_info v : velems) {1445Element ve = null;1446int offset = 0;1447int index = 0;1448switch (v.tag) {1449case StackMapTable_attribute.verification_type_info.ITEM_Top:1450ve = new Element("ITEM_Top");1451break;1452case StackMapTable_attribute.verification_type_info.ITEM_Integer:1453ve = new Element("ITEM_Integer");1454break;1455case StackMapTable_attribute.verification_type_info.ITEM_Float:1456ve = new Element("ITEM_Float");1457break;1458case StackMapTable_attribute.verification_type_info.ITEM_Long:1459ve = new Element("ITEM_Long");1460break;1461case StackMapTable_attribute.verification_type_info.ITEM_Double:1462ve = new Element("ITEM_Double");1463break;1464case StackMapTable_attribute.verification_type_info.ITEM_Null:1465ve = new Element("ITEM_Null");1466break;1467case StackMapTable_attribute.verification_type_info.ITEM_Uninitialized:1468ve = new Element("ITEM_Uninitialized");1469offset = ((StackMapTable_attribute.Uninitialized_variable_info) v).offset;1470ve.setAttr("offset", "" + offset);1471break;1472case StackMapTable_attribute.verification_type_info.ITEM_UninitializedThis:1473ve = new Element("ITEM_UnitializedtThis");1474break;1475case StackMapTable_attribute.verification_type_info.ITEM_Object:1476ve = new Element("ITEM_Object");1477index = ((StackMapTable_attribute.Object_variable_info) v).cpool_index;1478ve.setAttr("class", x.getCpString(index));1479break;1480default:1481ve = new Element("Unknown");1482}1483Element kindE = new Element(kind);1484kindE.setAttr("tag", "" + v.tag);1485container.add(kindE);1486kindE.add(ve);1487}1488container.trimToSize();1489return container;1490}1491}14921493class InstructionVisitor implements Instruction.KindVisitor<Element, Void> {14941495final ClassReader x;1496final ClassFile cf;14971498public InstructionVisitor(ClassReader x, ClassFile cf) {1499this.x = x;1500this.cf = cf;1501}15021503public Element visit(Instruction i) {1504Element ie = i.accept(this, null);1505ie.trimToSize();1506return ie;1507}15081509@Override1510public Element visitNoOperands(Instruction i, Void p) {1511Opcode o = i.getOpcode();1512Element e = new Element(i.getMnemonic());1513if (o.opcode > 0xab && o.opcode <= 0xb1) {1514e.setAttr("pc", "" + i.getPC());1515}1516return e;1517}15181519@Override1520public Element visitArrayType(Instruction i, TypeKind tk, Void p) {1521Element ie = new Element(i.getMnemonic());1522ie.setAttr("num", "" + tk.value);1523ie.setAttr("val", tk.name);1524return ie;1525}15261527@Override1528public Element visitBranch(Instruction i, int i1, Void p) {1529Element ie = new Element(i.getMnemonic());1530ie.setAttr("lab", "" + (i.getPC() + i1));1531return ie;1532}15331534@Override1535public Element visitConstantPoolRef(Instruction i, int i1, Void p) {1536Element ie = new Element(i.getMnemonic());1537ie.setAttr("ref", x.getCpString(i1));1538return ie;1539}15401541@Override1542public Element visitConstantPoolRefAndValue(Instruction i, int i1, int i2, Void p) {1543// workaround for a potential bug in classfile1544Element ie = new Element(i.getMnemonic());1545if (i.getOpcode().equals(Opcode.IINC_W)) {1546ie.setAttr("loc", "" + i1);1547ie.setAttr("num", "" + i2);1548} else {1549ie.setAttr("ref", x.getCpString(i1));1550ie.setAttr("val", "" + i2);1551}1552return ie;1553}15541555@Override1556public Element visitLocal(Instruction i, int i1, Void p) {1557Element ie = new Element(i.getMnemonic());1558ie.setAttr("loc", "" + i1);1559return ie;1560}15611562@Override1563public Element visitLocalAndValue(Instruction i, int i1, int i2, Void p) {1564Element ie = new Element(i.getMnemonic());1565ie.setAttr("loc", "" + i1);1566ie.setAttr("num", "" + i2);1567return ie;1568}15691570@Override1571public Element visitLookupSwitch(Instruction i, int i1, int i2, int[] ints,1572int[] ints1, Void p) {1573Element ie = new Element(i.getMnemonic());1574int pc = i.getPC();1575ie.setAttr("lab", "" + (pc + i1));1576for (int k = 0 ; k < i2 ; k++) {1577Element c = new Element("Case");1578c.setAttr("num", "" + (ints[k]));1579c.setAttr("lab", "" + (pc + ints1[k]));1580c.trimToSize();1581ie.add(c);1582}1583return ie;1584}15851586@Override1587public Element visitTableSwitch(Instruction i, int i1, int i2, int i3,1588int[] ints, Void p) {1589Element ie = new Element(i.getMnemonic());1590int pc = i.getPC();1591ie.setAttr("lab", "" + (pc + i1));1592for (int k : ints) {1593Element c = new Element("Case");1594c.setAttr("num", "" + (k + i2));1595c.setAttr("lab", "" + (pc + k));1596c.trimToSize();1597ie.add(c);1598}1599return ie;1600}16011602@Override1603public Element visitValue(Instruction i, int i1, Void p) {1604Element ie = new Element(i.getMnemonic());1605ie.setAttr("num", "" + i1);1606return ie;1607}16081609@Override1610public Element visitUnknown(Instruction i, Void p) {1611Element e = new Element(i.getMnemonic());1612e.setAttr("pc", "" + i.getPC());1613e.setAttr("opcode", "" + i.getOpcode().opcode);1614return e;1615}1616}16171618class AnnotationsElementVisitor implements Annotation.element_value.Visitor<Element, Element> {1619final ClassReader x;1620final ClassFile cf;16211622public AnnotationsElementVisitor(ClassReader x, ClassFile cf) {1623this.x = x;1624this.cf = cf;1625}16261627public Element visit(Annotation.element_value v, Element p) {1628return v.accept(this, p);1629}16301631@Override1632public Element visitPrimitive(Primitive_element_value e, Element p) {1633Element el = new Element("String");1634el.setAttr("val", x.getCpString(e.const_value_index));1635el.trimToSize();1636return el;1637}16381639@Override1640public Element visitEnum(Enum_element_value e, Element p) {1641Element el = new Element("Enum");1642el.setAttr("name", x.getCpString(e.const_name_index));1643el.setAttr("type", x.getCpString(e.type_name_index));1644el.trimToSize();1645return el;1646}16471648@Override1649public Element visitClass(Class_element_value c, Element p) {1650Element el = new Element("Class");1651el.setAttr("name", x.getCpString(c.class_info_index));1652el.trimToSize();1653return el;1654}16551656@Override1657public Element visitAnnotation(Annotation_element_value a, Element p) {1658Element el = new Element("Annotation");1659Annotation anno = a.annotation_value;1660for (Annotation.element_value_pair evp : anno.element_value_pairs) {1661Element child = visit(evp.value, el);1662if (child != null) {1663el.add(child);1664}1665}1666el.trimToSize();1667return el;1668}16691670@Override1671public Element visitArray(Array_element_value a, Element p) {1672Element el = new Element("Array");1673for (Annotation.element_value v : a.values) {1674Element child = visit(v, el);1675if (child != null) {1676el.add(child);1677}1678}1679el.trimToSize();1680return el;1681}1682}168316841685