1 32 package net.sf.retrotranslator.transformer; 33 34 import net.sf.retrotranslator.runtime.asm.*; 35 import static net.sf.retrotranslator.runtime.asm.Opcodes.*; 36 import net.sf.retrotranslator.runtime.impl.RuntimeTools; 37 import net.sf.retrotranslator.runtime.java.lang.Enum_; 38 39 42 class EnumVisitor extends ClassAdapter { 43 44 private static final String ENUM_NAME = Type.getInternalName(Enum_.class); 45 private static final String SET_ENUM_CONSTANTS_NAME = "setEnumConstants"; 46 private static final String SET_ENUM_CONSTANTS_DESC = 47 TransformerTools.descriptor(void.class, Class .class, Enum_[].class); 48 49 private Type type; 50 51 public EnumVisitor(final ClassVisitor cv) { 52 super(cv); 53 } 54 55 public void visit(final int version, final int access, final String name, 56 final String signature, final String superName, final String [] interfaces) { 57 super.visit(version, access, name, signature, superName, interfaces); 58 if ((access & ACC_ENUM) != 0 && ENUM_NAME.equals(superName)) { 59 type = TransformerTools.getTypeByInternalName(name); 60 } 61 } 62 63 public MethodVisitor visitMethod(final int access, final String name, 64 final String desc, final String signature, final String [] exceptions) { 65 MethodVisitor visitor = super.visitMethod(access, name, desc, signature, exceptions); 66 if (visitor == null || type == null || !name.equals(RuntimeTools.STATIC_NAME)) return visitor; 67 return new MethodAdapter(visitor) { 68 69 private boolean alreadyProcessed; 70 71 public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { 72 if (opcode == INVOKESTATIC && owner.equals(ENUM_NAME) && 73 name.equals(SET_ENUM_CONSTANTS_NAME) && desc.equals(SET_ENUM_CONSTANTS_DESC)) { 74 alreadyProcessed = true; 75 } 76 super.visitMethodInsn(opcode, owner, name, desc); 77 } 78 79 public void visitInsn(final int opcode) { 80 if (opcode == RETURN && !alreadyProcessed) { 81 mv.visitLdcInsn(type); 82 mv.visitMethodInsn(INVOKESTATIC, type.getInternalName(), "values", "()[" + type.getDescriptor()); 83 mv.visitMethodInsn(INVOKESTATIC, ENUM_NAME, SET_ENUM_CONSTANTS_NAME, SET_ENUM_CONSTANTS_DESC); 84 } 85 super.visitInsn(opcode); 86 } 87 }; 88 } 89 } 90 | Popular Tags |