Skip to content

Commit 31b323b

Browse files
authored
Add compile-time validation for effectively always cancelling listeners (#112)
Suggests changing code that always returns true inside a possibly cancelling listener into a void return always cancelling listener, as the latter allows EventBus to know at listener registration time and can perform additional optimisations based on that knowledge.
1 parent 0196fc0 commit 31b323b

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

eventbus-test/src/test/java/net/minecraftforge/eventbus/test/compiletime/SubscribeEventValidatorTests.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ public void testSubscribeEventReturnTypeCancellable() {
7474
""");
7575
assertThat(compilation).hadWarningContaining("consider using a void return type");
7676

77+
compilation = compile("""
78+
@SubscribeEvent
79+
boolean alwaysCancellingEvent(CancelableEvent event) { return true; }
80+
""");
81+
assertThat(compilation).hadWarningContaining("consider using a void return type");
82+
assertThat(compilation).hadWarningContaining("alwaysCancelling = true");
83+
7784
compilation = compile("""
7885
@SubscribeEvent(alwaysCancelling = true)
7986
void alwaysCancellingEvent(CancelableEvent event) {}

eventbus-validator/src/main/java/net/minecraftforge/eventbus/validator/SubscribeEventValidator.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,20 @@ private void validate(ExecutableElement method) {
104104
var scanner = new ReturnScanner();
105105
scanner.scan(methodPath, null);
106106

107-
if (scanner.sawReturn && !scanner.sawNonLiteralReturn && scanner.sawLiteralFalse && !scanner.sawLiteralTrue) {
108-
// if we get here, all returns in this method are literal `return false;` statements
109-
processingEnv.getMessager().printWarning(
110-
"Listener always returns false, consider using a void return type instead",
111-
method
112-
);
107+
if (scanner.sawReturn && !scanner.sawNonLiteralReturn) {
108+
if (scanner.sawLiteralFalse && !scanner.sawLiteralTrue) {
109+
// if we get here, all returns in this method are literal `return false;` statements
110+
processingEnv.getMessager().printWarning(
111+
"Listener always returns false, consider using a void return type instead",
112+
method
113+
);
114+
} else if (scanner.sawLiteralTrue && !scanner.sawLiteralFalse) {
115+
// if we get here, all returns in this method are literal `return true;` statements
116+
processingEnv.getMessager().printWarning(
117+
"Listener always returns true, consider using a void return type combined with @SubscribeEvent(alwaysCancelling = true) or CancellableEventBus#addListener(true, ...) instead",
118+
method
119+
);
120+
}
113121
}
114122
}
115123
}

0 commit comments

Comments
 (0)