Skip to content

Commit

Permalink
SPIGOT-7820: Enum changes - duplicate method name
Browse files Browse the repository at this point in the history
  • Loading branch information
DerFrZocker authored and md-5 committed Jul 7, 2024
1 parent a0d2d6a commit aceddcd
Showing 1 changed file with 34 additions and 1 deletion.
35 changes: 34 additions & 1 deletion src/main/java/org/bukkit/craftbukkit/util/Commodore.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package org.bukkit.craftbukkit.util;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.io.ByteStreams;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
Expand Down Expand Up @@ -160,11 +163,18 @@ private static void convert(File in, File out) {

public static byte[] convert(byte[] b, final String pluginName, final ApiVersion pluginVersion, final Set<String> activeCompatibilities) {
final boolean modern = pluginVersion.isNewerThanOrSameAs(ApiVersion.FLATTENING);
final boolean enumCompatibility = pluginVersion.isOlderThanOrSameAs(ApiVersion.getOrCreateVersion("1.20.6")) && activeCompatibilities.contains("enum-compatibility-mode");
ClassReader cr = new ClassReader(b);
ClassWriter cw = new ClassWriter(0); // TODO 2024-06-22: Open PR to ASM to included interface in handle hash

List<String> methodEnumSignatures = getMethodSignatures(b);
Multimap<String, String> enumLessToEnum = HashMultimap.create();
for (String method : methodEnumSignatures) {
enumLessToEnum.put(method.replace("Ljava/lang/Enum;", "Ljava/lang/Object;"), method);
}

ClassVisitor visitor = cw;
if (pluginVersion.isOlderThanOrSameAs(ApiVersion.getOrCreateVersion("1.20.6")) && activeCompatibilities.contains("enum-compatibility-mode")) {
if (enumCompatibility) {
visitor = new LimitedClassRemapper(cw, new SimpleRemapper(ENUM_RENAMES));
}

Expand Down Expand Up @@ -232,6 +242,15 @@ public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, Str

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (enumCompatibility && (access & Opcodes.ACC_SYNTHETIC) != 0 && (access & Opcodes.ACC_BRIDGE) != 0 && desc.contains("Ljava/lang/Object;")) {
// SPIGOT-7820: Do not use object method if enum method is present
// The object method does only redirect to the enum method
Collection<String> result = enumLessToEnum.get(desc.replace("Ljava/lang/Enum;", "Ljava/lang/Object;") + " " + name);
if (result.size() == 2) {
name = name + "_BUKKIT_UNUSED";
}
}

return new MethodVisitor(api, super.visitMethod(access, name, desc, signature, exceptions)) {

@Override
Expand Down Expand Up @@ -644,6 +663,20 @@ public static boolean rerouteMethods(Set<String> activeCompatibilities, ApiVersi
return false;
}

private static List<String> getMethodSignatures(byte[] clazz) {
List<String> methods = new ArrayList<>();
ClassReader cr = new ClassReader(clazz);
cr.accept(new ClassVisitor(Opcodes.ASM9) {
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
methods.add(descriptor + " " + name);
return null;
}
}, 0);

return methods;
}

private static String buildMethodName(RerouteMethodData rerouteMethodData) {
return BUKKIT_GENERATED_METHOD_PREFIX + rerouteMethodData.targetOwner().replace('/', '_') + "_" + rerouteMethodData.targetName();
}
Expand Down

0 comments on commit aceddcd

Please sign in to comment.