From a5576ac5e7e3144cebee41530a9020191d0c76f5 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Tue, 11 Apr 2023 23:25:38 +0200 Subject: [PATCH] feat: type erasure is now handled correctly --- .../ftbsc/lll/processor/tools/ASTUtils.java | 32 +++++++++++++++++-- .../tools/containers/MethodContainer.java | 9 +++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/main/java/ftbsc/lll/processor/tools/ASTUtils.java b/src/main/java/ftbsc/lll/processor/tools/ASTUtils.java index 498a8f0..f8b05b5 100644 --- a/src/main/java/ftbsc/lll/processor/tools/ASTUtils.java +++ b/src/main/java/ftbsc/lll/processor/tools/ASTUtils.java @@ -12,10 +12,8 @@ import ftbsc.lll.proxies.ProxyType; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.*; import javax.lang.model.type.*; -import javax.tools.Diagnostic; import java.lang.annotation.Annotation; import java.util.Collection; -import java.util.HashMap; import java.util.List; import java.util.function.Function; import java.util.stream.Collectors; @@ -302,6 +300,36 @@ public class ASTUtils { } } + /** + * Tries to find the method being overloaded by the given {@link ExecutableElement}. + * In case of multiple layers of overloading, it finds the original one. In case of + * no overloading, it returns the given method. + * @param context the {@link TypeElement} representing the parent class + * @param method an {@link ExecutableElement} representing the overloading method + * @param env the {@link ProcessingEnvironment} to perform the operation in + * @return the original overloaded method, or the given method if it was not found + * @since 0.5.2 + */ + public static ExecutableElement findOverloadedMethod( + TypeElement context, ExecutableElement method, ProcessingEnvironment env) { + if (context.getSuperclass().getKind() == TypeKind.NONE) + return method; + + for (Element elem : context.getEnclosedElements()) { + if (elem.getKind() != ElementKind.METHOD) + continue; + if (env.getElementUtils().overrides(method, (ExecutableElement) elem, context)) { + method = (ExecutableElement) elem; + break; //found + } + } + + return findOverloadedMethod( + (TypeElement) env.getTypeUtils().asElement(context.getSuperclass()), + method, env + ); + } + /** * Utility method for finding out what type of proxy a field is. * It will fail if the return type is not a known type of proxy. diff --git a/src/main/java/ftbsc/lll/processor/tools/containers/MethodContainer.java b/src/main/java/ftbsc/lll/processor/tools/containers/MethodContainer.java index 6619dd6..adb6361 100644 --- a/src/main/java/ftbsc/lll/processor/tools/containers/MethodContainer.java +++ b/src/main/java/ftbsc/lll/processor/tools/containers/MethodContainer.java @@ -9,6 +9,7 @@ import ftbsc.lll.processor.tools.obfuscation.ObfuscationMapper; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; import static ftbsc.lll.processor.tools.ASTUtils.*; @@ -72,7 +73,13 @@ public class MethodContainer { this.name = name; this.descriptor = descriptor; } else { - this.elem = (ExecutableElement) findMember(parent, name, descriptor, descriptor != null && strict, false, env); + this.elem = findOverloadedMethod( //to prevent type erasure from messing it all up + (TypeElement) this.parent.elem, + (ExecutableElement) findMember( + parent, name, descriptor, descriptor != null && strict,false, env + ), env + ); + this.name = this.elem.getSimpleName().toString(); this.descriptor = descriptorFromExecutableElement(this.elem, env); }