mirror of
https://github.com/zaaarf/geb-processor.git
synced 2024-11-23 01:14:49 +01:00
feat: proper error handling
This commit is contained in:
parent
17398e89db
commit
ca13fffd0e
3 changed files with 94 additions and 7 deletions
|
@ -0,0 +1,52 @@
|
||||||
|
package ftbsc.geb.exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when there is something wrong with a listener method.
|
||||||
|
*/
|
||||||
|
public class BadListenerArgumentsException extends RuntimeException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The constructor. It's not meant to be used as is, refer to the subclasses
|
||||||
|
* @param message the message to pass along to the superclass
|
||||||
|
*/
|
||||||
|
protected BadListenerArgumentsException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when the number of arguments is off.
|
||||||
|
*/
|
||||||
|
public static class Count extends BadListenerArgumentsException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The public constructor.
|
||||||
|
* @param clazz the fully-qualified name of the parent class
|
||||||
|
* @param method the annotated listener method
|
||||||
|
* @param count the number of arguments found
|
||||||
|
*/
|
||||||
|
public Count(String clazz, String method, int count) {
|
||||||
|
super(String.format(
|
||||||
|
"An error occurred while evaluating method %s::%s: found %d arguments, expected 1!",
|
||||||
|
clazz, method, count));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when the argument is of the wrong type.
|
||||||
|
*/
|
||||||
|
public static class Type extends BadListenerArgumentsException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The public constructor.
|
||||||
|
* @param clazz the fully-qualified name of the parent class
|
||||||
|
* @param method the annotated listener method
|
||||||
|
* @param parameterName the name of the parameter
|
||||||
|
*/
|
||||||
|
public Type(String clazz, String method, String parameterName) {
|
||||||
|
super(String.format(
|
||||||
|
"The parameter %s of %s::%s does not implement the IEvent interface!",
|
||||||
|
parameterName, clazz, method
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package ftbsc.geb.exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when a parent of a listener method does not implement the
|
||||||
|
* appropriate interface,
|
||||||
|
*/
|
||||||
|
public class MissingInterfaceException extends RuntimeException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The public constructor.
|
||||||
|
* @param clazz the fully-qualified name of the parent class
|
||||||
|
* @param method the annotated listener method
|
||||||
|
*/
|
||||||
|
public MissingInterfaceException(String clazz, String method) {
|
||||||
|
super(String.format("The parent of %s::%s does not implement the IListener interface!", clazz, method));
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,12 +5,16 @@ import ftbsc.geb.api.IEvent;
|
||||||
import ftbsc.geb.api.IEventDispatcher;
|
import ftbsc.geb.api.IEventDispatcher;
|
||||||
import ftbsc.geb.api.IListener;
|
import ftbsc.geb.api.IListener;
|
||||||
import ftbsc.geb.api.annotations.Listen;
|
import ftbsc.geb.api.annotations.Listen;
|
||||||
|
import ftbsc.geb.exceptions.BadListenerArgumentsException;
|
||||||
|
import ftbsc.geb.exceptions.MissingInterfaceException;
|
||||||
|
|
||||||
import javax.annotation.processing.AbstractProcessor;
|
import javax.annotation.processing.AbstractProcessor;
|
||||||
import javax.annotation.processing.RoundEnvironment;
|
import javax.annotation.processing.RoundEnvironment;
|
||||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||||
import javax.lang.model.element.*;
|
import javax.lang.model.element.*;
|
||||||
|
import javax.lang.model.type.TypeKind;
|
||||||
import javax.lang.model.type.TypeMirror;
|
import javax.lang.model.type.TypeMirror;
|
||||||
|
import javax.tools.Diagnostic;
|
||||||
import javax.tools.FileObject;
|
import javax.tools.FileObject;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.StandardLocation;
|
import javax.tools.StandardLocation;
|
||||||
|
@ -88,23 +92,37 @@ public class GEBProcessor extends AbstractProcessor {
|
||||||
* @param target the {@link Element} that was annotated with {@link Listen}
|
* @param target the {@link Element} that was annotated with {@link Listen}
|
||||||
*/
|
*/
|
||||||
private void processListener(Element target) {
|
private void processListener(Element target) {
|
||||||
if(!(target instanceof ExecutableElement))
|
|
||||||
return; //TODO throw error
|
|
||||||
|
|
||||||
ExecutableElement listener = (ExecutableElement) target; //this cast will never fail
|
ExecutableElement listener = (ExecutableElement) target; //this cast will never fail
|
||||||
|
|
||||||
//ensure the parent is instance of IListener
|
//ensure the parent is instance of IListener
|
||||||
TypeMirror parentType = listener.getEnclosingElement().asType();
|
TypeMirror parentType = listener.getEnclosingElement().asType();
|
||||||
if(!this.processingEnv.getTypeUtils().isAssignable(parentType, this.listenerInterface))
|
if(!this.processingEnv.getTypeUtils().isAssignable(parentType, this.listenerInterface))
|
||||||
return; //TODO throw error, parent doesn't implement the interface
|
throw new MissingInterfaceException(
|
||||||
|
listener.getEnclosingElement().getSimpleName().toString(),
|
||||||
|
listener.getSimpleName().toString());
|
||||||
|
|
||||||
//ensure the listener method has only a single IEvent parameter
|
//ensure the listener method has only one parameter
|
||||||
List<? extends VariableElement> params = listener.getParameters();
|
List<? extends VariableElement> params = listener.getParameters();
|
||||||
if(listener.getParameters().size() != 1)
|
if(listener.getParameters().size() != 1)
|
||||||
return; //TODO throw error, bad parameter amount
|
throw new BadListenerArgumentsException.Count(
|
||||||
|
listener.getEnclosingElement().getSimpleName().toString(),
|
||||||
|
listener.getSimpleName().toString(),
|
||||||
|
params.size());
|
||||||
|
|
||||||
|
//ensure said parameter implements IEvent
|
||||||
TypeMirror event = params.get(0).asType();
|
TypeMirror event = params.get(0).asType();
|
||||||
if(!this.processingEnv.getTypeUtils().isAssignable(event, this.eventInterface))
|
if(!this.processingEnv.getTypeUtils().isAssignable(event, this.eventInterface))
|
||||||
return; //TODO throw error, bad parameter type
|
throw new BadListenerArgumentsException.Type(
|
||||||
|
listener.getEnclosingElement().getSimpleName().toString(),
|
||||||
|
listener.getSimpleName().toString(),
|
||||||
|
params.get(0).getSimpleName().toString());
|
||||||
|
|
||||||
|
//warn about return type
|
||||||
|
if(!listener.getReturnType().getKind().equals(TypeKind.VOID))
|
||||||
|
this.processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, String.format(
|
||||||
|
"The method %s::%s has a return type: please note that it will be ignored.",
|
||||||
|
listener.getEnclosingElement().getSimpleName().toString(),
|
||||||
|
listener.getSimpleName().toString()));
|
||||||
|
|
||||||
if(!this.listenerMap.containsKey(event))
|
if(!this.listenerMap.containsKey(event))
|
||||||
this.listenerMap.put(event, new HashSet<>());
|
this.listenerMap.put(event, new HashSet<>());
|
||||||
|
|
Loading…
Reference in a new issue