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.asm.signature.*; 37 38 41 class DuplicateInterfacesVisitor extends ClassAdapter { 42 43 private final SystemLogger logger; 44 private final MethodCounter counter; 45 46 public DuplicateInterfacesVisitor(ClassVisitor cv, SystemLogger logger, MethodCounter counter) { 47 super(cv); 48 this.logger = logger; 49 this.counter = counter; 50 } 51 52 public void visit(int version, int access, String name, String signature, String superName, String [] interfaces) { 53 String [] cleanInterfaces = cleanInterfaces(interfaces); 54 String cleanSignature = cleanInterfaces == interfaces ? signature : cleanSignature(signature); 55 super.visit(version, access, name, cleanSignature, superName, cleanInterfaces); 56 } 57 58 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String [] exceptions) { 59 counter.increment(name, desc); 60 return super.visitMethod(access, name, desc, signature, exceptions); 61 } 62 63 private String [] cleanInterfaces(String [] values) { 64 if (values == null) return null; 65 Set<String > set = new LinkedHashSet<String >(); 66 for (String s : values) { 67 if (!set.add(s) && logger != null) { 68 logger.logForFile(Level.VERBOSE, "Repetitive interface name removed: " + s.replace('/', '.')); 69 } 70 } 71 if (set.size() == values.length) return values; 72 return set.toArray(new String [set.size()]); 73 } 74 75 private String cleanSignature(String signature) { 76 if (signature == null) return null; 77 SignatureWriter writer = new SignatureWriter(); 78 new SignatureReader(signature).accept(new SignatureCleaningVisitor(writer)); 79 return writer.toString(); 80 } 81 82 private static class SignatureCleaningVisitor extends SignatureAdapter { 83 84 private Set<String > interfaces = new HashSet<String >(); 85 86 public SignatureCleaningVisitor(final SignatureVisitor visitor) { 87 super(visitor); 88 } 89 90 private void addInterface(String signature) { 91 new SignatureReader(signature).acceptType(super.visitInterface()); 92 } 93 94 public SignatureVisitor visitInterface() { 95 final SignatureWriter writer = new SignatureWriter(); 96 return new SignatureAdapter(writer) { 97 98 private String interfaceName; 99 100 public void visitClassType(String name) { 101 super.visitClassType(name); 102 interfaceName = name; 103 } 104 105 public void visitEnd() { 106 super.visitEnd(); 107 if (interfaces.add(interfaceName)) { 108 addInterface(writer.toString()); 109 } 110 } 111 112 }; 113 } 114 115 } 116 117 } 118 | Popular Tags |