From 7719039473d649fadf7f36269f4d6fb979037978 Mon Sep 17 00:00:00 2001 From: Runemoro Date: Wed, 20 Jun 2018 18:45:52 -0400 Subject: [PATCH] Overriding methods can return a superclass of the method they override --- .../javaremapper/GeneratingMapping.java | 31 +----------------- .../dimdev/javaremapper/SimpleRemapper.java | 18 ++++++----- .../org/dimdev/javaremapper/TypeUtil.java | 32 +++++++++++++++++++ 3 files changed, 43 insertions(+), 38 deletions(-) create mode 100644 src/main/java/org/dimdev/javaremapper/TypeUtil.java diff --git a/src/main/java/org/dimdev/javaremapper/GeneratingMapping.java b/src/main/java/org/dimdev/javaremapper/GeneratingMapping.java index 31b3361..3db6d7c 100644 --- a/src/main/java/org/dimdev/javaremapper/GeneratingMapping.java +++ b/src/main/java/org/dimdev/javaremapper/GeneratingMapping.java @@ -1,7 +1,5 @@ package org.dimdev.javaremapper; -import org.objectweb.asm.Type; - import java.util.Set; public class GeneratingMapping extends Mapping { @@ -61,7 +59,7 @@ public String getMethod(String className, String methodName, String methodDescri // Don't remap inherited methods, their name is inherited from the parent's mapping for (String superclass : inheritanceProvider.getAllSuperclasses(className)) { for (MemberRef ref : inheritanceProvider.getInheritableMethods(superclass)) { - if (methodName.equals(ref.name) && methodDescriptorOverrides(methodDescriptor, ref.descriptor)) { + if (methodName.equals(ref.name) && TypeUtil.methodDescriptorOverrides(inheritanceProvider, methodDescriptor, ref.descriptor)) { return null; } } @@ -74,31 +72,4 @@ public String getMethod(String className, String methodName, String methodDescri } return result; } - - private boolean methodDescriptorOverrides(String descriptor1, String descriptor2) { - // Check return types - Type ret1 = Type.getReturnType(descriptor1); - Type ret2 = Type.getReturnType(descriptor2); - if (!ret1.equals(ret2) && !inheritanceProvider.getAllSuperclasses(ret1.getClassName()).contains(ret2.getClassName())) { - return false; - } - - // Check argument types - Type[] args1 = Type.getArgumentTypes(descriptor1); - Type[] args2 = Type.getArgumentTypes(descriptor2); - - if (args1.length != args2.length) return false; - - for (int i = 0; i < args1.length; i++) { - String class1 = args1[i].getClassName(); - String class2 = args2[i].getClassName(); - - // Arguments must be the identical in Java, not supertypes - if (!class1.equals(class2)) { - return false; - } - } - - return true; - } } diff --git a/src/main/java/org/dimdev/javaremapper/SimpleRemapper.java b/src/main/java/org/dimdev/javaremapper/SimpleRemapper.java index 523b811..4c2f600 100644 --- a/src/main/java/org/dimdev/javaremapper/SimpleRemapper.java +++ b/src/main/java/org/dimdev/javaremapper/SimpleRemapper.java @@ -42,15 +42,17 @@ public String mapMethodName(String owner, String name, String desc) { String newName = mapping.getMethod(owner, name, desc); for (String superclass : inheritanceProvider.getAllSuperclasses(owner)) { - if (inheritanceProvider.getInheritableMethods(superclass).contains(new MemberRef(name, desc))) { - String inheritedNewName = mapping.getMethod(superclass, name, desc); - if (inheritedNewName != null) { - if (newName != null && !inheritedNewName.equals(newName)) { - System.err.println("Method inheritance problem: " + owner + "." + name + desc + - " inherits " + superclass + "." + name + desc + - " but " + newName + " != " + inheritedNewName); + for (MemberRef ref : inheritanceProvider.getInheritableMethods(superclass)) { + if (name.equals(ref.name) && TypeUtil.methodDescriptorOverrides(inheritanceProvider, desc, ref.descriptor)) { + String inheritedNewName = mapping.getMethod(superclass, name, desc); + if (inheritedNewName != null) { + if (newName != null && !inheritedNewName.equals(newName)) { + System.err.println("Method inheritance problem: " + owner + "." + name + desc + + " inherits " + superclass + "." + name + desc + + " but " + newName + " != " + inheritedNewName); + } + return inheritedNewName; } - return inheritedNewName; } } } diff --git a/src/main/java/org/dimdev/javaremapper/TypeUtil.java b/src/main/java/org/dimdev/javaremapper/TypeUtil.java new file mode 100644 index 0000000..1d021e9 --- /dev/null +++ b/src/main/java/org/dimdev/javaremapper/TypeUtil.java @@ -0,0 +1,32 @@ +package org.dimdev.javaremapper; + +import org.objectweb.asm.Type; + +public final class TypeUtil { + public static boolean methodDescriptorOverrides(InheritanceProvider inheritanceProvider, String descriptor1, String descriptor2) { + // Check return types + Type ret1 = Type.getReturnType(descriptor1); + Type ret2 = Type.getReturnType(descriptor2); + if (!ret1.equals(ret2) && !inheritanceProvider.getAllSuperclasses(ret1.getClassName()).contains(ret2.getClassName())) { + return false; + } + + // Check argument types + Type[] args1 = Type.getArgumentTypes(descriptor1); + Type[] args2 = Type.getArgumentTypes(descriptor2); + + if (args1.length != args2.length) return false; + + for (int i = 0; i < args1.length; i++) { + String class1 = args1[i].getClassName(); + String class2 = args2[i].getClassName(); + + // Arguments must be the identical in Java, not supertypes + if (!class1.equals(class2)) { + return false; + } + } + + return true; + } +}