From 4d330a731bf44bcca291a23407c06ed063193921 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Tue, 4 Jun 2024 20:03:51 +0200 Subject: feat: better inner classes api, removed deprecation warnings since that stuff is there to stay --- .../lll/processor/containers/ClassContainer.java | 58 ++++++++++++---------- .../lll/processor/containers/FieldContainer.java | 17 +++---- 2 files changed, 40 insertions(+), 35 deletions(-) (limited to 'src/main/java/ftbsc/lll/processor/containers') diff --git a/src/main/java/ftbsc/lll/processor/containers/ClassContainer.java b/src/main/java/ftbsc/lll/processor/containers/ClassContainer.java index 047bc47..e4ba1ca 100644 --- a/src/main/java/ftbsc/lll/processor/containers/ClassContainer.java +++ b/src/main/java/ftbsc/lll/processor/containers/ClassContainer.java @@ -32,13 +32,13 @@ public class ClassContainer { public final TypeElement elem; /** - * Private constructor, called from {@link #from(Annotation, Function, String, ProcessorOptions)}. + * Private constructor, called from {@link #from(Annotation, Function, String[], ProcessorOptions)}. * @param fqn the fully-qualified name of the target class * @param innerNames an array of Strings containing the path to the inner class, may be null * @param options the {@link ProcessorOptions} to be used */ private ClassContainer(String fqn, String[] innerNames, ProcessorOptions options) { - //find and validate + // find and validate TypeElement elem = options.env.getElementUtils().getTypeElement(fqn); if(elem == null) @@ -49,23 +49,11 @@ public class ClassContainer { ); if(innerNames != null) { + boolean skip = false; for(String inner : innerNames) { - if(inner == null) continue; - fqnBuilder.append("$").append(inner); - try { - int anonClassCounter = Integer.parseInt(inner); - //anonymous classes cannot be validated! - if(options.anonymousClassWarning) - options.env.getMessager().printMessage( - Diagnostic.Kind.WARNING, - String.format( - "Anonymous classes cannot be verified by the processor. The existence of %s$%s is not guaranteed!", - fqnBuilder, anonClassCounter - ) - ); - elem = null; - break; - } catch(NumberFormatException exc) { + if(inner != null) fqnBuilder.append('$').append(inner); + if(skip) continue; + if(shouldValidate(inner)) { elem = elem .getEnclosedElements() .stream() @@ -74,11 +62,24 @@ public class ClassContainer { .filter(e -> e.getSimpleName().contentEquals(inner)) .findFirst() .orElse(null); + } else { + options.env.getMessager().printMessage( + Diagnostic.Kind.WARNING, + String.format( + "Anonymous class %s$%s and its children cannot be verified by the processor!", + fqnBuilder, + inner + ) + ); + elem = null; + skip = true; + continue; } if(elem == null) throw new TargetNotFoundException("class", inner); } } + this.data = getClassData(fqnBuilder.toString(), options.mapper); this.elem = elem; } @@ -87,17 +88,22 @@ public class ClassContainer { * Safely extracts a {@link Class} from an annotation and gets its fully qualified name. * @param ann the annotation containing the class * @param classFunction the annotation function returning the class - * @param innerName a string containing the inner class name or nothing + * @param innerNames a string containing the inner class name or nothing * @param options the {@link ProcessorOptions} to be used * @param the type of the annotation carrying the information * @return the fully qualified name of the given class * @since 0.5.0 */ - public static ClassContainer from(T ann, Function> classFunction, String innerName, ProcessorOptions options) { - String fqn; - String[] inner; - fqn = getTypeFromAnnotation(ann, classFunction, options.env).toString(); - inner = innerName.equals("") ? null : innerName.split("//$"); + public static ClassContainer from( + T ann, + Function> classFunction, + String[] innerNames, + ProcessorOptions options + ) { + String fqn = getTypeFromAnnotation(ann, classFunction, options.env).toString(); + String[] inner = innerNames != null && innerNames.length != 0 + ? String.join("$", innerNames).split("\\$") + : null; return new ClassContainer(fqn, inner, options); } @@ -123,8 +129,8 @@ public class ClassContainer { * @since 0.5.0 */ public static ClassContainer findOrFallback(ClassContainer fallback, Patch p, Find f, ProcessorOptions options) { - if(f == null) return ClassContainer.from(p, Patch::value, p.innerName(), options); - ClassContainer cl = ClassContainer.from(f, Find::value, f.innerName(), options); + if(f == null) return ClassContainer.from(p, Patch::value, p.inner(), options); + ClassContainer cl = ClassContainer.from(f, Find::value, f.inner(), options); return cl.data.name.equals("java/lang/Object") ? fallback : cl; } } diff --git a/src/main/java/ftbsc/lll/processor/containers/FieldContainer.java b/src/main/java/ftbsc/lll/processor/containers/FieldContainer.java index a9c56ee..7a2a913 100644 --- a/src/main/java/ftbsc/lll/processor/containers/FieldContainer.java +++ b/src/main/java/ftbsc/lll/processor/containers/FieldContainer.java @@ -58,7 +58,7 @@ public class FieldContainer { */ private FieldContainer(ClassContainer parent, String name, String descriptor, ProcessorOptions options) { this.parent = parent; - if(parent.elem == null) { //unverified + if(parent.elem == null) { // unverified if(descriptor == null) throw new AmbiguousDefinitionException("Cannot use name-based lookups for fields of unverifiable classes!"); this.elem = null; @@ -81,9 +81,9 @@ public class FieldContainer { * @since 0.5.0 */ public static FieldContainer from(VariableElement finder, ProcessorOptions options) { - //the parent always has a @Patch annotation + // the parent always has a @Patch annotation Patch patchAnn = finder.getEnclosingElement().getAnnotation(Patch.class); - //the finder always has a @Find annotation + // the finder always has a @Find annotation Find f = finder.getAnnotation(Find.class); ClassContainer parent = ClassContainer.findOrFallback( @@ -96,12 +96,11 @@ public class FieldContainer { if(fieldType.toString().equals("java.lang.Object")) { descriptor = null; } else { - if(fieldType.getKind() != TypeKind.VOID && !fieldType.getKind().isPrimitive()) - descriptor = //jank af but this is temporary anyway - "L" + ClassContainer.from( - f, Find::type, f.typeInner(), options - ).data.nameMapped + ";"; - else descriptor = descriptorFromType(fieldType, options.env); + if(fieldType.getKind() != TypeKind.VOID && !fieldType.getKind().isPrimitive()) { + descriptor = String.format("L%s;", ClassContainer.from( + f, Find::type, f.typeInner(), options + ).data.nameMapped); + } else descriptor = descriptorFromType(fieldType, options.env); } return new FieldContainer(parent, name, descriptor, options); -- cgit v1.2.3-56-ga3b1