Compare commits

...

2 commits

3 changed files with 31 additions and 13 deletions

View file

@ -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);

View file

@ -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;
@ -64,11 +65,28 @@ public class MethodContainer {
ExecutableElement tmp = (ExecutableElement) findMember( ExecutableElement tmp = (ExecutableElement) findMember(
parent, name, descriptor, descriptor != null && strict,false, options.env parent, name, descriptor, descriptor != null && strict,false, options.env
); );
this.elem = bridge ? findSyntheticBridge((TypeElement) this.parent.elem, tmp, options.env) : tmp; this.elem = bridge ? findSyntheticBridge(this.parent.elem, tmp, options.env) : tmp;
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)
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.nameMapped,
topData.signature.descriptor
);
} 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);
} }

View file

@ -116,7 +116,7 @@ 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
@ -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
@ -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