mirror of
https://github.com/zaaarf/lillero-processor.git
synced 2024-11-14 17:49:19 +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
|
//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'
|
||||||
}
|
}
|
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.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.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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