chore: big code refactoring

This commit is contained in:
zaaarf 2023-02-27 17:26:55 +01:00
parent 824f9fb9a2
commit 928638cb7a
No known key found for this signature in database
GPG key ID: 82240E075E31FA4C
5 changed files with 107 additions and 111 deletions

View file

@ -12,5 +12,5 @@ repositories {
//TODO: figure out how to make annotationProcessor inherit its dependencies //TODO: figure out how to make annotationProcessor inherit its dependencies
dependencies { dependencies {
implementation 'com.squareup:javapoet:1.13.0' implementation 'com.squareup:javapoet:1.13.0'
implementation 'ftbsc:lll:0.2.1' implementation 'ftbsc:lll:0.2.2'
} }

View file

@ -0,0 +1,88 @@
package ftbsc.lll.processor;
import com.squareup.javapoet.ArrayTypeName;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeName;
import ftbsc.lll.tools.DescriptorBuilder;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import java.lang.annotation.Annotation;
/**
* Collection of static utils that didn't really fit into the main class.
*/
public class ASTUtils {
/**
* Finds, among the methods of a class cl, the one annotated with ann, and tries to build
* a {@link ExecutableElement} from it.
* In case of multiple occurrences, only the first one is returned.
* No check existance check is performed within the method.
* @param cl the {@link ExecutableElement} for the class containing the desired method
* @param ann the {@link Class} corresponding to the desired annotation
* @return the {@link MethodSpec} representing the desired method
*/
@SuppressWarnings("OptionalGetWithoutIsPresent")
public static ExecutableElement findAnnotatedMethod(TypeElement cl, Class<? extends Annotation> ann) {
return (ExecutableElement) cl.getEnclosedElements()
.stream()
.filter(e -> e.getAnnotation(ann) != null)
.findFirst()
.get(); //will never be null so can ignore warning
}
/**
* Builds a type descriptor from the given {@link TypeMirror}
* @param t the {@link TypeMirror} representing the desired type
* @return a {@link String} containing the relevant descriptor
*/
public static String descriptorFromType(TypeMirror t) {
TypeName type = TypeName.get(t);
StringBuilder desc = new StringBuilder();
//add array brackets
while(type instanceof ArrayTypeName) {
desc.append("[");
type = ((ArrayTypeName) type).componentType;
}
if(type instanceof ClassName) {
ClassName var = (ClassName) type;
desc.append(DescriptorBuilder.nameToDescriptor(var.canonicalName(), 0));
} else {
if(TypeName.BOOLEAN.equals(type))
desc.append("Z");
else if(TypeName.CHAR.equals(type))
desc.append("C");
else if(TypeName.BYTE.equals(type))
desc.append("B");
else if(TypeName.SHORT.equals(type))
desc.append("S");
else if(TypeName.INT.equals(type))
desc.append("I");
else if(TypeName.FLOAT.equals(type))
desc.append("F");
else if(TypeName.LONG.equals(type))
desc.append("J");
else if(TypeName.DOUBLE.equals(type))
desc.append("D");
else if(TypeName.VOID.equals(type))
desc.append("V");
}
return desc.toString();
}
/**
* Builds a method descriptor from the given {@link ExecutableElement}.
* @param m the {@link ExecutableElement} for the method
* @return a {@link String} containing the relevant descriptor
*/
public static String descriptorFromMethodSpec(ExecutableElement m) {
StringBuilder methodSignature = new StringBuilder();
methodSignature.append("(");
m.getParameters().forEach(p -> methodSignature.append(descriptorFromType(p.asType())));
methodSignature.append(")");
methodSignature.append(descriptorFromType(m.getReturnType()));
return methodSignature.toString();
}
}

View file

@ -5,8 +5,6 @@ import ftbsc.lll.IInjector;
import ftbsc.lll.processor.annotations.Injector; import ftbsc.lll.processor.annotations.Injector;
import ftbsc.lll.processor.annotations.Patch; import ftbsc.lll.processor.annotations.Patch;
import ftbsc.lll.processor.annotations.Target; import ftbsc.lll.processor.annotations.Target;
import ftbsc.lll.processor.exceptions.MappingNotFoundException;
import ftbsc.lll.processor.exceptions.MappingsFileNotFoundException;
import ftbsc.lll.tools.DescriptorBuilder; import ftbsc.lll.tools.DescriptorBuilder;
import ftbsc.lll.tools.SrgMapper; import ftbsc.lll.tools.SrgMapper;
@ -29,6 +27,9 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static ftbsc.lll.processor.ASTUtils.descriptorFromMethodSpec;
import static ftbsc.lll.processor.ASTUtils.findAnnotatedMethod;
/** /**
* The actual annotation processor behind the magic. * The actual annotation processor behind the magic.
* It (implicitly) implements the {@link Processor} interface by extending {@link AbstractProcessor}. * It (implicitly) implements the {@link Processor} interface by extending {@link AbstractProcessor}.
@ -102,91 +103,6 @@ public class LilleroProcessor extends AbstractProcessor {
} }
} }
/**
* Finds, among the methods of a class cl, the one annotated with ann, and tries to build
* a {@link MethodSpec} from it.
* In case of multiple occurrences, only the first one is returned.
* No check existance check is performed within the method.
* @param cl the {@link TypeElement} for the class containing the desired method
* @param ann the {@link Class} corresponding to the desired annotation
* @return the {@link MethodSpec} representing the desired method
*/
@SuppressWarnings("OptionalGetWithoutIsPresent")
private static ExecutableElement findAnnotatedMethod(TypeElement cl, Class<? extends Annotation> ann) {
return (ExecutableElement) cl.getEnclosedElements()
.stream()
.filter(e -> e.getAnnotation(ann) != null)
.findFirst()
.get(); //will never be null so can ignore warning
}
/**
* Builds a {@link MethodSpec} for a public method whose body simply returns a {@link String}.
* @param name the name of the method
* @param returnString the {@link String} to return
* @return the built {@link MethodSpec}
*/
private static MethodSpec buildStringReturnMethod(String name, String returnString) {
return MethodSpec.methodBuilder(name)
.addModifiers(Modifier.PUBLIC)
.returns(String.class)
.addStatement("return $S", returnString)
.build();
}
/**
* Builds a type descriptor from the given {@link TypeMirror}
* @param t the {@link TypeMirror} representing the desired type
* @return a {@link String} containing the relevant descriptor
*/
public static String descriptorFromType(TypeMirror t) {
TypeName type = TypeName.get(t);
StringBuilder desc = new StringBuilder();
//add array brackets
while(type instanceof ArrayTypeName) {
desc.append("[");
type = ((ArrayTypeName) type).componentType;
}
if(type instanceof ClassName) {
ClassName var = (ClassName) type;
desc.append(DescriptorBuilder.nameToDescriptor(var.canonicalName(), 0));
} else {
if(TypeName.BOOLEAN.equals(type))
desc.append("Z");
else if(TypeName.CHAR.equals(type))
desc.append("C");
else if(TypeName.BYTE.equals(type))
desc.append("B");
else if(TypeName.SHORT.equals(type))
desc.append("S");
else if(TypeName.INT.equals(type))
desc.append("I");
else if(TypeName.FLOAT.equals(type))
desc.append("F");
else if(TypeName.LONG.equals(type))
desc.append("J");
else if(TypeName.DOUBLE.equals(type))
desc.append("D");
else if(TypeName.VOID.equals(type))
desc.append("V");
}
return desc.toString();
}
/**
* Builds a method descriptor from the given {@link ExecutableElement}.
* @param m the {@link ExecutableElement} for the method
* @return a {@link String} containing the relevant descriptor
*/
public static String descriptorFromMethodSpec(ExecutableElement m) {
StringBuilder methodSignature = new StringBuilder();
methodSignature.append("(");
m.getParameters().forEach(p -> methodSignature.append(descriptorFromType(p.asType())));
methodSignature.append(")");
methodSignature.append(descriptorFromType(m.getReturnType()));
return methodSignature.toString();
}
/** /**
* Generates the Injector corresponding to the given class. * Generates the Injector corresponding to the given class.
* Basically implements the {@link IInjector} interface for you. * Basically implements the {@link IInjector} interface for you.
@ -201,7 +117,7 @@ public class LilleroProcessor extends AbstractProcessor {
StandardCharsets.UTF_8)).lines()); StandardCharsets.UTF_8)).lines());
is.close(); is.close();
} catch(IOException e) { } catch(IOException e) {
throw new MappingsFileNotFoundException(); throw new RuntimeException("Could not open the specified TSRG file!", e);
} }
Patch ann = cl.getAnnotation(Patch.class); Patch ann = cl.getAnnotation(Patch.class);
@ -212,8 +128,6 @@ public class LilleroProcessor extends AbstractProcessor {
targetClassCanonicalName = e.getTypeMirror().toString(); targetClassCanonicalName = e.getTypeMirror().toString();
} //pretty sure class names de facto never change but better safe than sorry } //pretty sure class names de facto never change but better safe than sorry
String targetClassSrgName = mapper.getMcpClass(targetClassCanonicalName.replace('.', '/')); String targetClassSrgName = mapper.getMcpClass(targetClassCanonicalName.replace('.', '/'));
if(targetClassSrgName == null)
throw new MappingNotFoundException(targetClassCanonicalName);
ExecutableElement targetMethod = findAnnotatedMethod(cl, Target.class); ExecutableElement targetMethod = findAnnotatedMethod(cl, Target.class);
String targetMethodDescriptor = descriptorFromMethodSpec(targetMethod); String targetMethodDescriptor = descriptorFromMethodSpec(targetMethod);
@ -222,9 +136,6 @@ public class LilleroProcessor extends AbstractProcessor {
targetMethod.getSimpleName() + " " + targetMethodDescriptor targetMethod.getSimpleName() + " " + targetMethodDescriptor
); );
if(targetMethodSrgName == null)
throw new MappingNotFoundException(targetMethod.getSimpleName() + " " + targetMethodDescriptor);
ExecutableElement injectorMethod = findAnnotatedMethod(cl, Injector.class); ExecutableElement injectorMethod = findAnnotatedMethod(cl, Injector.class);
Element packageElement = cl.getEnclosingElement(); Element packageElement = cl.getEnclosingElement();
@ -274,6 +185,20 @@ public class LilleroProcessor extends AbstractProcessor {
this.generatedInjectors.add(injectorClassName); this.generatedInjectors.add(injectorClassName);
} }
/**
* Builds a {@link MethodSpec} for a public method whose body simply returns a {@link String}.
* @param name the name of the method
* @param returnString the {@link String} to return
* @return the built {@link MethodSpec}
*/
private static MethodSpec buildStringReturnMethod(String name, String returnString) {
return MethodSpec.methodBuilder(name)
.addModifiers(Modifier.PUBLIC)
.returns(String.class)
.addStatement("return $S", returnString)
.build();
}
/** /**
* Generates the Service Provider file for the generated injectors. * Generates the Service Provider file for the generated injectors.
*/ */

View file

@ -1,7 +0,0 @@
package ftbsc.lll.processor.exceptions;
public class MappingNotFoundException extends RuntimeException {
public MappingNotFoundException(String mapping) {
super("Could not find mapping for " + mapping + "!");
}
}

View file

@ -1,10 +0,0 @@
package ftbsc.lll.processor.exceptions;
/**
* Thrown upon failure to locate the output.tsrg file at runtime.
*/
public class MappingsFileNotFoundException extends RuntimeException {
public MappingsFileNotFoundException() {
super("Could not find a mappings file in the specified location!");
}
}