mirror of
https://github.com/zaaarf/lillero-processor.git
synced 2024-12-23 02:54:52 +01:00
chore: big code refactoring
This commit is contained in:
parent
824f9fb9a2
commit
928638cb7a
5 changed files with 107 additions and 111 deletions
|
@ -12,5 +12,5 @@ repositories {
|
|||
//TODO: figure out how to make annotationProcessor inherit its dependencies
|
||||
dependencies {
|
||||
implementation 'com.squareup:javapoet:1.13.0'
|
||||
implementation 'ftbsc:lll:0.2.1'
|
||||
implementation 'ftbsc:lll:0.2.2'
|
||||
}
|
88
src/main/java/ftbsc/lll/processor/ASTUtils.java
Normal file
88
src/main/java/ftbsc/lll/processor/ASTUtils.java
Normal 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();
|
||||
}
|
||||
}
|
|
@ -5,8 +5,6 @@ import ftbsc.lll.IInjector;
|
|||
import ftbsc.lll.processor.annotations.Injector;
|
||||
import ftbsc.lll.processor.annotations.Patch;
|
||||
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.SrgMapper;
|
||||
|
||||
|
@ -29,6 +27,9 @@ import java.util.List;
|
|||
import java.util.Set;
|
||||
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.
|
||||
* 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.
|
||||
* Basically implements the {@link IInjector} interface for you.
|
||||
|
@ -201,7 +117,7 @@ public class LilleroProcessor extends AbstractProcessor {
|
|||
StandardCharsets.UTF_8)).lines());
|
||||
is.close();
|
||||
} catch(IOException e) {
|
||||
throw new MappingsFileNotFoundException();
|
||||
throw new RuntimeException("Could not open the specified TSRG file!", e);
|
||||
}
|
||||
|
||||
Patch ann = cl.getAnnotation(Patch.class);
|
||||
|
@ -212,8 +128,6 @@ public class LilleroProcessor extends AbstractProcessor {
|
|||
targetClassCanonicalName = e.getTypeMirror().toString();
|
||||
} //pretty sure class names de facto never change but better safe than sorry
|
||||
String targetClassSrgName = mapper.getMcpClass(targetClassCanonicalName.replace('.', '/'));
|
||||
if(targetClassSrgName == null)
|
||||
throw new MappingNotFoundException(targetClassCanonicalName);
|
||||
|
||||
ExecutableElement targetMethod = findAnnotatedMethod(cl, Target.class);
|
||||
String targetMethodDescriptor = descriptorFromMethodSpec(targetMethod);
|
||||
|
@ -222,9 +136,6 @@ public class LilleroProcessor extends AbstractProcessor {
|
|||
targetMethod.getSimpleName() + " " + targetMethodDescriptor
|
||||
);
|
||||
|
||||
if(targetMethodSrgName == null)
|
||||
throw new MappingNotFoundException(targetMethod.getSimpleName() + " " + targetMethodDescriptor);
|
||||
|
||||
ExecutableElement injectorMethod = findAnnotatedMethod(cl, Injector.class);
|
||||
|
||||
Element packageElement = cl.getEnclosingElement();
|
||||
|
@ -274,6 +185,20 @@ public class LilleroProcessor extends AbstractProcessor {
|
|||
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.
|
||||
*/
|
||||
|
|
|
@ -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 + "!");
|
||||
}
|
||||
}
|
|
@ -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!");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue