001 package org.shiftone.jrat.inject.bytecode.asm;
002
003
004 import org.objectweb.asm.ClassAdapter;
005 import org.objectweb.asm.ClassVisitor;
006 import org.objectweb.asm.MethodVisitor;
007 import org.objectweb.asm.Opcodes;
008 import org.shiftone.jrat.inject.bytecode.Modifier;
009 import org.shiftone.jrat.util.log.Logger;
010
011
012 /**
013 * @author jeff@shiftone.org (Jeff Drost)
014 */
015 public class ClassInitClassVisitor extends ClassAdapter implements Constants, Opcodes {
016
017 private static final Logger LOG = Logger.getLogger(ClassInitClassVisitor.class);
018 private boolean clinitVisited = false;
019 private String className;
020
021 public ClassInitClassVisitor(final ClassVisitor cv) {
022 super(cv);
023 }
024
025
026 public void visit(final int version, final int access, final String name, final String signature,
027 final String superName, final String[] interfaces) {
028
029 clinitVisited = false;
030 className = name;
031
032 super.visit(version, access, name, signature, superName, interfaces);
033 }
034
035
036 public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature,
037 final String[] exceptions) {
038
039 MethodVisitor visitor = super.visitMethod(access, name, desc, signature, exceptions);
040
041 if (classInitName.equals(name)) {
042 clinitVisited = true;
043 visitor = new ClassInitMethodVisitor(className, visitor);
044 }
045
046 return visitor;
047 }
048
049
050 public void visitEnd() {
051
052 if (!clinitVisited) {
053
054 // LOG.info("adding new <clinit> method to " + className);
055 MethodVisitor clinit = visitMethod(Modifier.PRIVATE_STATIC, classInitName, classInitDesc, null, null);
056
057 clinit.visitCode();
058 clinit.visitInsn(RETURN);
059 clinit.visitEnd();
060 } else {
061
062 // LOG.info("class already had <clinit> method " + className);
063 }
064
065 super.visitEnd();
066 }
067 }