1 32 package net.sf.retrotranslator.transformer; 33 34 import java.util.*; 35 import net.sf.retrotranslator.runtime.asm.*; 36 import net.sf.retrotranslator.runtime.impl.*; 37 38 41 class ReferenceVerifyingVisitor extends GenericClassVisitor { 42 43 private ClassReaderFactory factory; 44 private SystemLogger logger; 45 private Set<String > warnings; 46 47 public ReferenceVerifyingVisitor(ClassReaderFactory factory, SystemLogger logger) { 48 super(new EmptyVisitor()); 49 this.factory = factory; 50 this.logger = logger; 51 } 52 53 public int verify(byte[] bytes) { 54 warnings = new LinkedHashSet<String >(); 55 new ClassReader(bytes).accept(this, true); 56 return warnings.size(); 57 } 58 59 protected String typeName(String s) { 60 if (s == null) return null; 61 try { 62 factory.getClassReader(s); 63 } catch (ClassNotFoundException e) { 64 println("Class not found: " + getClassInfo(e.getMessage())); 65 } 66 return s; 67 } 68 69 protected void visitFieldInstruction(MethodVisitor visitor, int opcode, String owner, String name, String desc) { 70 super.visitFieldInstruction(visitor, opcode, owner, name, desc); 71 boolean stat = (opcode == Opcodes.GETSTATIC || opcode == Opcodes.PUTSTATIC); 72 try { 73 int found = new MemberFinder(factory, false, stat, name, desc).findIn(owner, null); 74 if (found == 0) { 75 println(getFieldInfo(owner, stat, name, desc, "not found")); 76 } else if (found > 1) { 77 println(getFieldInfo(owner, stat, name, desc, "duplicated")); 78 } 79 } catch (ClassNotFoundException e) { 80 cannotVerify(getFieldInfo(owner, stat, name, desc, "not verified"), e); 81 } 82 } 83 84 protected void visitMethodInstruction(MethodVisitor visitor, int opcode, String owner, String name, String desc) { 85 super.visitMethodInstruction(visitor, opcode, owner, name, desc); 86 if (owner.startsWith("[")) return; 87 boolean stat = (opcode == Opcodes.INVOKESTATIC); 88 try { 89 int found = new MemberFinder(factory, true, stat, name, desc).findIn(owner, null); 90 if (found == 0) { 91 println(getMethodInfo(owner, stat, name, desc, "not found")); 92 } else if (found > 1) { 93 println(getMethodInfo(owner, stat, name, desc, "duplicated")); 94 } 95 } catch (ClassNotFoundException e) { 96 cannotVerify(getMethodInfo(owner, stat, name, desc, "not verified"), e); 97 } 98 } 99 100 private void cannotVerify(String text, ClassNotFoundException e) { 101 println(text + " (class not found: " + getClassInfo(e.getMessage()) + ")"); 102 } 103 104 private void println(String text) { 105 if (!warnings.contains(text)) { 106 warnings.add(text); 107 logger.logForFile(Level.WARNING, text); 108 } 109 } 110 111 private static String getClassInfo(String name) { 112 return name.replace('/', '.'); 113 } 114 115 private static String getFieldInfo(String owner, boolean stat, String name, String desc, String message) { 116 StringBuffer buffer = new StringBuffer ("Field ").append(message).append(": "); 117 if (stat) buffer.append("static "); 118 buffer.append(Type.getType(desc).getClassName()).append(' '); 119 buffer.append(getClassInfo(owner)).append('.').append(name); 120 return buffer.toString(); 121 } 122 123 private static String getMethodInfo(String owner, boolean stat, String name, String desc, String message) { 124 StringBuffer buffer = new StringBuffer (); 125 if (name.equals(RuntimeTools.CONSTRUCTOR_NAME)) { 126 buffer.append("Constructor ").append(message).append(": "); 127 buffer.append(getClassInfo(owner)); 128 } else { 129 buffer.append("Method ").append(message).append(": "); 130 if (stat) buffer.append("static "); 131 buffer.append(Type.getReturnType(desc).getClassName()); 132 buffer.append(' ').append(getClassInfo(owner)).append('.').append(name); 133 } 134 buffer.append('('); 135 boolean first = true; 136 for (Type type : Type.getArgumentTypes(desc)) { 137 buffer.append(first ? "" : ",").append(type.getClassName()); 138 first = false; 139 } 140 return buffer.append(')').toString(); 141 } 142 } 143 | Popular Tags |