Filter cancelled events even when the declared class is not cancellable (#3798)
* Filter cancelled events even when the declared class is not cancellable * Remove InvalidCancelledListener test
This commit is contained in:
1 parent
b8e23db093
commit
90d0323ceb
4 files changed
+36
-66
No files matched your search
@@ -47,7 +47,6 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.spongepowered.api.event.Cancellable;
|
||||
import org.spongepowered.api.event.Event;
|
||||
import org.spongepowered.api.event.filter.Getter;
|
||||
import org.spongepowered.api.event.filter.IsCancelled;
|
||||
@@ -144,7 +143,7 @@ public class FilterGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cancellation && Cancellable.class.isAssignableFrom(parameters[0].clazz())) {
|
||||
if (!cancellation) {
|
||||
additional.add(new CancellationEventFilterDelegate(Tristate.FALSE));
|
||||
}
|
||||
|
||||
|
||||
+35
-12
@@ -30,6 +30,7 @@ import static org.objectweb.asm.Opcodes.ARETURN;
|
||||
import static org.objectweb.asm.Opcodes.CHECKCAST;
|
||||
import static org.objectweb.asm.Opcodes.IFEQ;
|
||||
import static org.objectweb.asm.Opcodes.IFNE;
|
||||
import static org.objectweb.asm.Opcodes.INSTANCEOF;
|
||||
import static org.objectweb.asm.Opcodes.INVOKEINTERFACE;
|
||||
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
@@ -60,21 +61,43 @@ public class CancellationEventFilterDelegate implements FilterDelegate {
|
||||
if (this.state == Tristate.UNDEFINED) {
|
||||
return locals;
|
||||
}
|
||||
if (!Cancellable.class.isAssignableFrom(method.parameterTypes()[0].clazz())) {
|
||||
throw new IllegalStateException("Attempted to filter a non-cancellable event type by its cancellation status");
|
||||
|
||||
final boolean checkCancellable = !Cancellable.class.isAssignableFrom(method.parameterTypes()[0].clazz());
|
||||
final String cancellableClassName = Type.getInternalName(Cancellable.class);
|
||||
final Label notCancelled = new Label();
|
||||
|
||||
if (checkCancellable) {
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitTypeInsn(INSTANCEOF, cancellableClassName);
|
||||
mv.visitJumpInsn(IFEQ, notCancelled);
|
||||
}
|
||||
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Cancellable.class));
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Cancellable.class), "isCancelled", "()Z", true);
|
||||
final Label success = new Label();
|
||||
if (this.state == Tristate.TRUE) {
|
||||
mv.visitJumpInsn(IFNE, success);
|
||||
} else {
|
||||
mv.visitJumpInsn(IFEQ, success);
|
||||
if (checkCancellable) {
|
||||
mv.visitTypeInsn(CHECKCAST, cancellableClassName);
|
||||
}
|
||||
mv.visitInsn(ACONST_NULL);
|
||||
mv.visitInsn(ARETURN);
|
||||
mv.visitLabel(success);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, cancellableClassName, "isCancelled", "()Z", true);
|
||||
|
||||
if (this.state == Tristate.TRUE) {
|
||||
final Label cancelled = new Label();
|
||||
mv.visitJumpInsn(IFNE, cancelled);
|
||||
|
||||
if (checkCancellable) {
|
||||
mv.visitLabel(notCancelled);
|
||||
}
|
||||
mv.visitInsn(ACONST_NULL);
|
||||
mv.visitInsn(ARETURN);
|
||||
|
||||
mv.visitLabel(cancelled);
|
||||
} else {
|
||||
mv.visitJumpInsn(IFEQ, notCancelled);
|
||||
|
||||
mv.visitInsn(ACONST_NULL);
|
||||
mv.visitInsn(ARETURN);
|
||||
|
||||
mv.visitLabel(notCancelled);
|
||||
}
|
||||
|
||||
return locals;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ import org.spongepowered.common.event.listener.DoubleListener;
|
||||
import org.spongepowered.common.event.listener.FirstLastCauseListener;
|
||||
import org.spongepowered.common.event.listener.GetterListener;
|
||||
import org.spongepowered.common.event.listener.IncludeExcludeListener;
|
||||
import org.spongepowered.common.event.listener.InvalidCancelledListener;
|
||||
import org.spongepowered.common.event.listener.InvalidIncludeExcludeListener;
|
||||
import org.spongepowered.common.event.listener.RootListener;
|
||||
import org.spongepowered.common.event.listener.SimpleListener;
|
||||
@@ -117,11 +116,6 @@ public class EventFilterTest {
|
||||
Assert.assertTrue("Listener annotated with @IsCancelled(Tristate.UNDEFINED) was not called!", listener.alwaysCalledWasCalled);
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void testCancelledEvent_InvalidListener() throws Exception {
|
||||
this.getListener(new InvalidCancelledListener(), "onEvent", UncancellableEvent.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncludeExcludeListener() throws Exception {
|
||||
IncludeExcludeListener listener = new IncludeExcludeListener();
|
||||
@@ -461,14 +455,6 @@ public class EventFilterTest {
|
||||
}
|
||||
}
|
||||
|
||||
public static class UncancellableEvent implements Event {
|
||||
|
||||
@Override
|
||||
public Cause getCause() {
|
||||
return TEST_CAUSE;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestObject {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* This file is part of Sponge, licensed under the MIT License (MIT).
|
||||
*
|
||||
* Copyright (c) SpongePowered <https://www.spongepowered.org>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package org.spongepowered.common.event.listener;
|
||||
|
||||
import org.spongepowered.api.event.Listener;
|
||||
import org.spongepowered.api.event.filter.IsCancelled;
|
||||
import org.spongepowered.common.event.EventFilterTest;
|
||||
|
||||
public class InvalidCancelledListener {
|
||||
|
||||
@Listener
|
||||
@IsCancelled
|
||||
public void onEvent(EventFilterTest.UncancellableEvent event) {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user