diff --git a/src/main/java/net/md_5/specialsource/AccessMap.java b/src/main/java/net/md_5/specialsource/AccessMap.java index 8935b7e..c45745c 100644 --- a/src/main/java/net/md_5/specialsource/AccessMap.java +++ b/src/main/java/net/md_5/specialsource/AccessMap.java @@ -174,17 +174,13 @@ public class AccessMap { public int applyMethodAccess(String className, String methodName, String methodDesc, int access) { int old = access; - - if (className.contains("FileConversionException")){ - System.out.println(""); - } access = apply("**", access); access = apply("*/* ()", access); access = apply(className + "/* ()", access); access = apply(className + "/" + methodName + " " + methodDesc, access); - if (access!= old) System.out.println("AT: method: "+className+"/"+methodName+" "+methodDesc+" "+old+" -> "+access); + // if (access!= old) System.out.println("AT: method: "+className+"/"+methodName+" "+methodDesc+" "+old+" -> "+access); return access; } diff --git a/src/main/java/net/md_5/specialsource/JarComparer.java b/src/main/java/net/md_5/specialsource/JarComparer.java index d57aa36..0f44d10 100644 --- a/src/main/java/net/md_5/specialsource/JarComparer.java +++ b/src/main/java/net/md_5/specialsource/JarComparer.java @@ -28,17 +28,26 @@ */ package net.md_5.specialsource; +import java.lang.reflect.Modifier; +import java.util.Collection; +import java.util.Map; +import net.md_5.specialsource.provider.InheritanceProvider; +import net.md_5.specialsource.provider.JarProvider; import net.md_5.specialsource.util.NoDupeList; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldNode; +import org.objectweb.asm.tree.MethodNode; public class JarComparer extends ClassVisitor { private final MethodReferenceFinder methodVisitor = new MethodReferenceFinder(); public final Jar jar; + private final InheritanceProvider inheritance; private String myName; public int iterDepth; public NoDupeList classes = new NoDupeList(); @@ -53,11 +62,15 @@ public class JarComparer extends ClassVisitor { classes.add(name); } } + if (type.getSort() == Type.ARRAY){ + visitType(type.getElementType()); + } } public JarComparer(Jar jar) { super(Opcodes.ASM4); this.jar = jar; + this.inheritance = new JarProvider(jar); } @Override @@ -69,6 +82,9 @@ public class JarComparer extends ClassVisitor { classes.add(implement); } } + if (jar.containsClass(superName)) { + classes.add(superName); + } } @Override @@ -81,15 +97,68 @@ public class JarComparer extends ClassVisitor { @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { Ownable method = new Ownable(NodeType.METHOD, myName, name, desc, access); + + String newN = getDeclarer(myName, method); + if (newN != null) { + method = new Ownable(method.type, newN, method.name, method.descriptor, method.access); + } methods.add(method); // FIXME: Scan return types too! for (Type t : Type.getArgumentTypes(desc)) { visitType(t); } + visitType(Type.getReturnType(desc)); return methodVisitor; } + public String getDeclarer(String currentParent, Ownable node) { + + String newParent = null; + + ClassNode n = jar.getNode(currentParent); + if (n == null) { + return newParent; + } + switch (node.type) { + case FIELD: + for (FieldNode field : n.fields) { + if (field.name.equals(node.name) && field.desc.equals(node.descriptor)) { + newParent = currentParent; + fields.remove(new Ownable(NodeType.FIELD, currentParent, node.name, node.descriptor, node.access)); + break; + } + } + break; + case METHOD: + for (MethodNode method : n.methods) { + if (method.name.equals(node.name) && method.desc.equals(node.descriptor) &&(method.access == -1 || (!Modifier.isPrivate(method.access) && !Modifier.isStatic(method.access))) ) { + newParent = currentParent; + methods.remove(new Ownable(NodeType.METHOD, currentParent, node.name, node.descriptor, node.access)); + methods.remove(node); + break; + } + } + break; + } + + if ((node.owner.equals(newParent) || newParent == null) && (node.access == -1 || (!Modifier.isPrivate(node.access) && !Modifier.isStatic(node.access)))) { + Collection parents = inheritance.getParents(currentParent); + + if (parents != null) { + // climb the inheritance tree + for (String parent : parents) { + newParent = getDeclarer(parent, node); + if (newParent != null) { + return newParent; + } + } + } + } + + return newParent; + } + private class MethodReferenceFinder extends MethodVisitor { public MethodReferenceFinder() { diff --git a/src/main/java/net/md_5/specialsource/Ownable.java b/src/main/java/net/md_5/specialsource/Ownable.java index 487bc90..47c6561 100644 --- a/src/main/java/net/md_5/specialsource/Ownable.java +++ b/src/main/java/net/md_5/specialsource/Ownable.java @@ -29,12 +29,14 @@ package net.md_5.specialsource; import lombok.Data; +import lombok.EqualsAndHashCode; /** * A class which can be used to represent a field, method, or anything else * which has an owner, a name and a descriptor. */ @Data +@EqualsAndHashCode(exclude = "access") public class Ownable { public final NodeType type; diff --git a/src/main/java/net/md_5/specialsource/UnsortedRemappingMethodAdapter.java b/src/main/java/net/md_5/specialsource/UnsortedRemappingMethodAdapter.java index af8fd33..1240e01 100644 --- a/src/main/java/net/md_5/specialsource/UnsortedRemappingMethodAdapter.java +++ b/src/main/java/net/md_5/specialsource/UnsortedRemappingMethodAdapter.java @@ -150,7 +150,7 @@ public class UnsortedRemappingMethodAdapter extends MethodVisitor { //Lex: Chang return access; } - private int findAccess(NodeType type, String owner, String name, String desc) { + public int findAccess(NodeType type, String owner, String name, String desc) { int access; access = findAccess(type, owner, name, desc, classRepo); if (access == -1) { diff --git a/src/main/java/net/md_5/specialsource/util/NoDupeList.java b/src/main/java/net/md_5/specialsource/util/NoDupeList.java index 5f9960f..bae5d16 100644 --- a/src/main/java/net/md_5/specialsource/util/NoDupeList.java +++ b/src/main/java/net/md_5/specialsource/util/NoDupeList.java @@ -64,6 +64,11 @@ public class NoDupeList implements Iterable { return backing.size(); } + public void remove(E e) { + set.remove(e); + backing.remove(e); + } + @Override public Iterator iterator() { return backing.iterator();