mirror of
https://github.com/zaaarf/geb-processor.git
synced 2024-11-24 18:24:49 +01:00
feat: static listeners, parameterzied IEventDispatcher
This commit is contained in:
parent
3238cf5fe8
commit
22a60c7ed3
1 changed files with 42 additions and 26 deletions
|
@ -56,9 +56,9 @@ public class GEBProcessor extends AbstractProcessor {
|
||||||
private TypeMirror cancelableEventInterface;
|
private TypeMirror cancelableEventInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link TypeMirror} representing the {@link IEventDispatcher} interface.
|
* A {@link TypeElement} representing the {@link IEventDispatcher} interface.
|
||||||
*/
|
*/
|
||||||
private TypeMirror dispatcherInterface;
|
private TypeElement dispatcherInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the processor with the given environment.
|
* Initializes the processor with the given environment.
|
||||||
|
@ -73,7 +73,7 @@ public class GEBProcessor extends AbstractProcessor {
|
||||||
this.eventInterface = env.getElementUtils()
|
this.eventInterface = env.getElementUtils()
|
||||||
.getTypeElement("ftbsc.geb.api.IEvent").asType();
|
.getTypeElement("ftbsc.geb.api.IEvent").asType();
|
||||||
this.dispatcherInterface = env.getElementUtils()
|
this.dispatcherInterface = env.getElementUtils()
|
||||||
.getTypeElement("ftbsc.geb.api.IEventDispatcher").asType();
|
.getTypeElement("ftbsc.geb.api.IEventDispatcher");
|
||||||
this.cancelableEventInterface = env.getElementUtils()
|
this.cancelableEventInterface = env.getElementUtils()
|
||||||
.getTypeElement("ftbsc.geb.api.IEventCancelable").asType();
|
.getTypeElement("ftbsc.geb.api.IEventCancelable").asType();
|
||||||
}
|
}
|
||||||
|
@ -123,14 +123,16 @@ public class GEBProcessor extends AbstractProcessor {
|
||||||
private void processListener(Element target) {
|
private void processListener(Element target) {
|
||||||
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
|
// if the method is not static, ensure the parent is an instance of IListener
|
||||||
TypeMirror parentType = listener.getEnclosingElement().asType();
|
if(!listener.getModifiers().contains(Modifier.STATIC)) {
|
||||||
if(!this.processingEnv.getTypeUtils().isAssignable(parentType, this.listenerInterface))
|
TypeMirror parentType = listener.getEnclosingElement().asType();
|
||||||
throw new MissingInterfaceException(
|
if(!this.processingEnv.getTypeUtils().isAssignable(parentType, this.listenerInterface))
|
||||||
listener.getEnclosingElement().getSimpleName().toString(),
|
throw new MissingInterfaceException(
|
||||||
listener.getSimpleName().toString());
|
listener.getEnclosingElement().getSimpleName().toString(),
|
||||||
|
listener.getSimpleName().toString());
|
||||||
|
}
|
||||||
|
|
||||||
//ensure the listener method has only one 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)
|
||||||
throw new BadListenerArgumentsException.Count(
|
throw new BadListenerArgumentsException.Count(
|
||||||
|
@ -138,7 +140,7 @@ public class GEBProcessor extends AbstractProcessor {
|
||||||
listener.getSimpleName().toString(),
|
listener.getSimpleName().toString(),
|
||||||
params.size());
|
params.size());
|
||||||
|
|
||||||
//ensure said parameter implements IEvent
|
// 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))
|
||||||
throw new BadListenerArgumentsException.Type(
|
throw new BadListenerArgumentsException.Type(
|
||||||
|
@ -146,7 +148,7 @@ public class GEBProcessor extends AbstractProcessor {
|
||||||
listener.getSimpleName().toString(),
|
listener.getSimpleName().toString(),
|
||||||
params.get(0).getSimpleName().toString());
|
params.get(0).getSimpleName().toString());
|
||||||
|
|
||||||
//warn about return type
|
// warn about return type
|
||||||
if(!listener.getReturnType().getKind().equals(TypeKind.VOID))
|
if(!listener.getReturnType().getKind().equals(TypeKind.VOID))
|
||||||
this.processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, String.format(
|
this.processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, String.format(
|
||||||
"The method %s::%s has a return type: please note that it will be ignored.",
|
"The method %s::%s has a return type: please note that it will be ignored.",
|
||||||
|
@ -164,8 +166,9 @@ public class GEBProcessor extends AbstractProcessor {
|
||||||
this.listenerMap.forEach((event, listeners) -> {
|
this.listenerMap.forEach((event, listeners) -> {
|
||||||
TypeElement eventClass = (TypeElement) this.processingEnv.getTypeUtils().asElement(event);
|
TypeElement eventClass = (TypeElement) this.processingEnv.getTypeUtils().asElement(event);
|
||||||
boolean cancelable = this.processingEnv.getTypeUtils().isAssignable(event, this.cancelableEventInterface);
|
boolean cancelable = this.processingEnv.getTypeUtils().isAssignable(event, this.cancelableEventInterface);
|
||||||
|
ClassName setName = ClassName.get("java.util", "Set");
|
||||||
|
|
||||||
ParameterSpec eventParam = ParameterSpec.builder(TypeName.get(this.eventInterface), "event").build();
|
ParameterSpec eventParam = ParameterSpec.builder(TypeName.get(event), "event").build();
|
||||||
ParameterSpec listenersParam = ParameterSpec.builder(
|
ParameterSpec listenersParam = ParameterSpec.builder(
|
||||||
ParameterizedTypeName.get(
|
ParameterizedTypeName.get(
|
||||||
ClassName.get("java.util", "Map"),
|
ClassName.get("java.util", "Map"),
|
||||||
|
@ -174,7 +177,7 @@ public class GEBProcessor extends AbstractProcessor {
|
||||||
WildcardTypeName.subtypeOf(TypeName.get(this.listenerInterface))
|
WildcardTypeName.subtypeOf(TypeName.get(this.listenerInterface))
|
||||||
),
|
),
|
||||||
ParameterizedTypeName.get(
|
ParameterizedTypeName.get(
|
||||||
ClassName.get("java.util", "Set"),
|
setName,
|
||||||
ClassName.get(this.listenerInterface)
|
ClassName.get(this.listenerInterface)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
@ -203,7 +206,8 @@ public class GEBProcessor extends AbstractProcessor {
|
||||||
done.put(listener.parent, i);
|
done.put(listener.parent, i);
|
||||||
String varName = String.format("listener%d", i);
|
String varName = String.format("listener%d", i);
|
||||||
callListenersBuilder.addStatement(
|
callListenersBuilder.addStatement(
|
||||||
"java.util.Set<$T> $L = $N.get($T.class)",
|
"$T<$T> $L = $N.get($T.class)", // Set is already imported per the parameters
|
||||||
|
setName,
|
||||||
this.listenerInterface,
|
this.listenerInterface,
|
||||||
varName,
|
varName,
|
||||||
listenersParam,
|
listenersParam,
|
||||||
|
@ -213,18 +217,28 @@ public class GEBProcessor extends AbstractProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
for(ListenerContainer listener : ordered) {
|
for(ListenerContainer listener : ordered) {
|
||||||
String varName = String.format("listener%d", done.get(listener.parent));
|
if(listener.method.getModifiers().contains(Modifier.STATIC)) {
|
||||||
callListenersBuilder
|
// if static call it directly
|
||||||
.addStatement("if($L != null) { for($T l : $L) {", varName, this.listenerInterface, varName)
|
callListenersBuilder.addStatement(
|
||||||
.addStatement(
|
"$T.$L($N);",
|
||||||
"if(l != null) (($T) l).$L(($T) $N); } }",
|
|
||||||
listener.parent,
|
listener.parent,
|
||||||
listener.method.getSimpleName().toString(),
|
listener.method.getSimpleName().toString(),
|
||||||
event,
|
|
||||||
eventParam
|
eventParam
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
// else iterate over its listeners
|
||||||
|
String varName = String.format("listener%d", done.get(listener.parent));
|
||||||
|
callListenersBuilder
|
||||||
|
.addStatement("if($L != null) { for($T l : $L) {", varName, this.listenerInterface, varName)
|
||||||
|
.addStatement(
|
||||||
|
"if(l != null) (($T) l).$L($N); } }",
|
||||||
|
listener.parent,
|
||||||
|
listener.method.getSimpleName().toString(),
|
||||||
|
eventParam
|
||||||
|
);
|
||||||
|
}
|
||||||
if(cancelable) callListenersBuilder
|
if(cancelable) callListenersBuilder
|
||||||
.addStatement("if((($T) $N).isCanceled()) return false", this.cancelableEventInterface, eventParam);
|
.addStatement("if($N.isCanceled()) return false", eventParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
callListenersBuilder.addStatement("return true");
|
callListenersBuilder.addStatement("return true");
|
||||||
|
@ -232,15 +246,17 @@ public class GEBProcessor extends AbstractProcessor {
|
||||||
MethodSpec eventType = MethodSpec.methodBuilder("eventType")
|
MethodSpec eventType = MethodSpec.methodBuilder("eventType")
|
||||||
.addModifiers(Modifier.PUBLIC)
|
.addModifiers(Modifier.PUBLIC)
|
||||||
.addAnnotation(Override.class)
|
.addAnnotation(Override.class)
|
||||||
.returns(Class.class)
|
.returns(ParameterizedTypeName.get(ClassName.get(Class.class), TypeName.get(event)))
|
||||||
.addStatement("return $T.class", event)
|
.addStatement("return $T.class", event)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
String clazzName = String.format("%sDispatcher", eventClass.getSimpleName());
|
String clazzName = String.format("%sDispatcher", eventClass.getSimpleName());
|
||||||
TypeSpec clazz = TypeSpec.classBuilder(clazzName)
|
TypeSpec clazz = TypeSpec.classBuilder(clazzName)
|
||||||
.addModifiers(Modifier.PUBLIC)
|
.addModifiers(Modifier.PUBLIC)
|
||||||
.addSuperinterface(this.dispatcherInterface)
|
.addSuperinterface(ParameterizedTypeName.get(
|
||||||
.addMethod(callListenersBuilder.build())
|
ClassName.get(this.dispatcherInterface),
|
||||||
|
TypeName.get(event)
|
||||||
|
)).addMethod(callListenersBuilder.build())
|
||||||
.addMethod(eventType)
|
.addMethod(eventType)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue