mirror of
https://github.com/zaaarf/lillero-processor.git
synced 2024-11-25 06:54:48 +01:00
fix: map overridden methods using top-level's name
This commit is contained in:
parent
2d944f31c5
commit
f93c7b9e16
3 changed files with 31 additions and 12 deletions
|
@ -6,7 +6,6 @@ import ftbsc.lll.processor.annotations.Find;
|
||||||
import ftbsc.lll.processor.annotations.Patch;
|
import ftbsc.lll.processor.annotations.Patch;
|
||||||
import ftbsc.lll.processor.ProcessorOptions;
|
import ftbsc.lll.processor.ProcessorOptions;
|
||||||
|
|
||||||
import javax.lang.model.element.Element;
|
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
|
@ -26,11 +25,11 @@ public class ClassContainer {
|
||||||
public final ClassData data;
|
public final ClassData data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link Element} corresponding to the class.
|
* The {@link TypeElement} corresponding to the class.
|
||||||
* May only be null intentionally i.e. when the associated element is
|
* May only be null intentionally i.e. when the associated element is
|
||||||
* an anonymous class or a child of an anonymous class.
|
* an anonymous class or a child of an anonymous class.
|
||||||
*/
|
*/
|
||||||
public final Element elem;
|
public final TypeElement elem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private constructor, called from {@link #from(Annotation, Function, String, ProcessorOptions)}.
|
* Private constructor, called from {@link #from(Annotation, Function, String, ProcessorOptions)}.
|
||||||
|
@ -40,7 +39,7 @@ public class ClassContainer {
|
||||||
*/
|
*/
|
||||||
private ClassContainer(String fqn, String[] innerNames, ProcessorOptions options) {
|
private ClassContainer(String fqn, String[] innerNames, ProcessorOptions options) {
|
||||||
//find and validate
|
//find and validate
|
||||||
Element elem = options.env.getElementUtils().getTypeElement(fqn);
|
TypeElement elem = options.env.getElementUtils().getTypeElement(fqn);
|
||||||
|
|
||||||
if(elem == null)
|
if(elem == null)
|
||||||
throw new TargetNotFoundException("class", fqn);
|
throw new TargetNotFoundException("class", fqn);
|
||||||
|
@ -71,6 +70,7 @@ public class ClassContainer {
|
||||||
.getEnclosedElements()
|
.getEnclosedElements()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(e -> e instanceof TypeElement)
|
.filter(e -> e instanceof TypeElement)
|
||||||
|
.map(e -> (TypeElement) e)
|
||||||
.filter(e -> e.getSimpleName().contentEquals(inner))
|
.filter(e -> e.getSimpleName().contentEquals(inner))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
|
|
|
@ -2,6 +2,7 @@ package ftbsc.lll.processor.containers;
|
||||||
|
|
||||||
import ftbsc.lll.exceptions.AmbiguousDefinitionException;
|
import ftbsc.lll.exceptions.AmbiguousDefinitionException;
|
||||||
import ftbsc.lll.exceptions.TargetNotFoundException;
|
import ftbsc.lll.exceptions.TargetNotFoundException;
|
||||||
|
import ftbsc.lll.mapper.data.ClassData;
|
||||||
import ftbsc.lll.mapper.utils.MappingUtils;
|
import ftbsc.lll.mapper.utils.MappingUtils;
|
||||||
import ftbsc.lll.mapper.data.MethodData;
|
import ftbsc.lll.mapper.data.MethodData;
|
||||||
import ftbsc.lll.processor.annotations.Find;
|
import ftbsc.lll.processor.annotations.Find;
|
||||||
|
@ -56,7 +57,7 @@ public class MethodContainer {
|
||||||
*/
|
*/
|
||||||
private MethodContainer(ClassContainer parent, String name, String descriptor, boolean strict, boolean bridge, ProcessorOptions options) {
|
private MethodContainer(ClassContainer parent, String name, String descriptor, boolean strict, boolean bridge, ProcessorOptions options) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
if(parent.elem == null) { //unverified
|
if(parent.elem == null) { // unverified
|
||||||
if(descriptor == null)
|
if(descriptor == null)
|
||||||
throw new AmbiguousDefinitionException("Cannot use name-based lookups for methods of unverifiable classes!");
|
throw new AmbiguousDefinitionException("Cannot use name-based lookups for methods of unverifiable classes!");
|
||||||
this.elem = null;
|
this.elem = null;
|
||||||
|
@ -68,7 +69,25 @@ public class MethodContainer {
|
||||||
name = this.elem.getSimpleName().toString();
|
name = this.elem.getSimpleName().toString();
|
||||||
descriptor = descriptorFromExecutableElement(this.elem, options.env);
|
descriptor = descriptorFromExecutableElement(this.elem, options.env);
|
||||||
}
|
}
|
||||||
this.data = getMethodData(parent.data.name, name, descriptor, options.mapper);
|
|
||||||
|
// some mapping formats omit methods if they are overriding a parent's method
|
||||||
|
// since there is no drawback but efficiency, let's use the top parent's name for that (when possible)
|
||||||
|
String mappedName = null;
|
||||||
|
if(this.parent.elem != null) {
|
||||||
|
ExecutableElement top = findOverloadedMethod(this.parent.elem, this.elem, options.env);
|
||||||
|
ClassData topParentData = getClassData(
|
||||||
|
internalNameFromType(top.getEnclosingElement().asType(), options.env),
|
||||||
|
options.mapper
|
||||||
|
);
|
||||||
|
MethodData topData = getMethodData(topParentData.name, name, descriptor, options.mapper);
|
||||||
|
this.data = new MethodData(
|
||||||
|
parent.data,
|
||||||
|
topData.signature.name,
|
||||||
|
topData.signature.descriptor,
|
||||||
|
topData.nameMapped
|
||||||
|
);
|
||||||
|
} else this.data = getMethodData(parent.data.name, name, descriptor, options.mapper);
|
||||||
|
|
||||||
this.descriptorObf = options.mapper == null ? this.data.signature.descriptor
|
this.descriptorObf = options.mapper == null ? this.data.signature.descriptor
|
||||||
: MappingUtils.mapMethodDescriptor(this.data.signature.descriptor, options.mapper, false);
|
: MappingUtils.mapMethodDescriptor(this.data.signature.descriptor, options.mapper, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,14 +116,14 @@ public class ASTUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the internal name from an {@link TypeMirror}.
|
* Gets the internal name from a {@link TypeMirror}.
|
||||||
* @param type the {@link TypeMirror} in question
|
* @param type the {@link TypeMirror} in question
|
||||||
* @param env the {@link ProcessingEnvironment} to perform the operation in
|
* @param env the {@link ProcessingEnvironment} to perform the operation in
|
||||||
* @return the internal name at compile time, or null if it wasn't a qualifiable
|
* @return the internal name at compile time, or null if it wasn't a qualifiable
|
||||||
* @since 0.5.1
|
* @since 0.5.1
|
||||||
*/
|
*/
|
||||||
public static String internalNameFromType(TypeMirror type, ProcessingEnvironment env) {
|
public static String internalNameFromType(TypeMirror type, ProcessingEnvironment env) {
|
||||||
//needed to actually turn elem into a TypeVariable, find it ignoring generics
|
// needed to actually turn elem into a TypeVariable, find it ignoring generics
|
||||||
Element elem = env.getTypeUtils().asElement(env.getTypeUtils().erasure(type));
|
Element elem = env.getTypeUtils().asElement(env.getTypeUtils().erasure(type));
|
||||||
StringBuilder fqnBuilder = new StringBuilder();
|
StringBuilder fqnBuilder = new StringBuilder();
|
||||||
while(elem.getEnclosingElement() != null && elem.getEnclosingElement().getKind() != ElementKind.PACKAGE) {
|
while(elem.getEnclosingElement() != null && elem.getEnclosingElement().getKind() != ElementKind.PACKAGE) {
|
||||||
|
@ -213,7 +213,7 @@ public class ASTUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link ClassData} corresponding to the given fully-qualified name,
|
* Gets the {@link ClassData} corresponding to the given internal name,
|
||||||
* or creates a false one with the same, non-obfuscated name twice.
|
* or creates a false one with the same, non-obfuscated name twice.
|
||||||
* @param name the internal name of the class to convert
|
* @param name the internal name of the class to convert
|
||||||
* @param mapper the {@link Mapper} to use, may be null
|
* @param mapper the {@link Mapper} to use, may be null
|
||||||
|
@ -222,7 +222,7 @@ public class ASTUtils {
|
||||||
*/
|
*/
|
||||||
public static ClassData getClassData(String name, Mapper mapper) {
|
public static ClassData getClassData(String name, Mapper mapper) {
|
||||||
try {
|
try {
|
||||||
name = name.replace('.', '/'); //just in case
|
name = name.replace('.', '/'); // just in case
|
||||||
if(mapper != null)
|
if(mapper != null)
|
||||||
return mapper.getClassData(name);
|
return mapper.getClassData(name);
|
||||||
} catch(MappingNotFoundException ignored) {}
|
} catch(MappingNotFoundException ignored) {}
|
||||||
|
@ -242,7 +242,7 @@ public class ASTUtils {
|
||||||
*/
|
*/
|
||||||
public static MethodData getMethodData(String parent, String name, String descriptor, Mapper mapper) {
|
public static MethodData getMethodData(String parent, String name, String descriptor, Mapper mapper) {
|
||||||
try {
|
try {
|
||||||
name = name.replace('.', '/'); //just in case
|
parent = parent.replace('.', '/'); // just in case
|
||||||
if(mapper != null)
|
if(mapper != null)
|
||||||
return mapper.getMethodData(parent, name, descriptor);
|
return mapper.getMethodData(parent, name, descriptor);
|
||||||
} catch(MappingNotFoundException ignored) {}
|
} catch(MappingNotFoundException ignored) {}
|
||||||
|
@ -360,7 +360,7 @@ public class ASTUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to find the "synthetic bridge" generated by the compiler for a certain overridden
|
* Tries to find the "synthetic bridge" generated by the compiler for a certain overridden
|
||||||
* method. A "bridge" only exists in cases where type erasure is involved (i.e. when the
|
* methods. A "bridge" only exists in cases where type erasure is involved (i.e. when the
|
||||||
* method being overridden uses a generic parameter that is not preserved in the overriding
|
* method being overridden uses a generic parameter that is not preserved in the overriding
|
||||||
* method).
|
* method).
|
||||||
* @param context the {@link TypeElement} representing the parent class
|
* @param context the {@link TypeElement} representing the parent class
|
||||||
|
|
Loading…
Reference in a new issue