diff --git a/core/pom.xml b/core/pom.xml index bfe2e16a5..3bd4fd492 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -58,8 +58,33 @@ 0.5.9 compile + + org.jetbrains.kotlin + kotlin-stdlib + 1.4.10 + provided + + + + org.jetbrains.kotlin + kotlin-maven-plugin + 1.4.10 + + + compile + process-sources + + compile + + + + + 1.8 + + + ${project.basedir}/../languages/core/ diff --git a/core/src/main/java/co/aikar/commands/RegisteredCommand.java b/core/src/main/java/co/aikar/commands/RegisteredCommand.java index ba8094350..0eeb97425 100644 --- a/core/src/main/java/co/aikar/commands/RegisteredCommand.java +++ b/core/src/main/java/co/aikar/commands/RegisteredCommand.java @@ -32,6 +32,9 @@ import co.aikar.commands.annotation.Private; import co.aikar.commands.annotation.Syntax; import co.aikar.commands.contexts.ContextResolver; +import co.aikar.commands.kotlin.JavaContinuation; +import kotlin.coroutines.Continuation; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.lang.annotation.Annotation; @@ -71,6 +74,7 @@ public class RegisteredCommand previousParam = null; - for (int i = 0; i < parameters.length; i++) { - CommandParameter parameter = this.parameters[i] = new CommandParameter<>(this, parameters[i], i, i == parameters.length - 1); + for (int i = 0; i < parametersLength; i++) { + CommandParameter parameter = this.parameters[i] = new CommandParameter<>(this, parameters[i], i, i == parametersLength - 1); if (previousParam != null) { previousParam.setNextParam(parameter); } @@ -157,7 +171,24 @@ void invoke(CommandIssuer sender, List args, CommandOperationContext con Map passedArgs = resolveContexts(sender, args); if (passedArgs == null) return; - Object obj = method.invoke(scope, passedArgs.values().toArray()); + Object[] methodArgs = passedArgs.values().toArray(); + if (isKotlinSuspendingFunction) { + Object[] methodArgsCopy = new Object[methodArgs.length + 1]; + System.arraycopy(methodArgs, 0, methodArgsCopy, 0, methodArgs.length); + methodArgs = methodArgsCopy; + methodArgs[methodArgs.length - 1] = new JavaContinuation() { + @Override + public void resumeWithException(@NotNull Throwable exception) { + handleException(sender, args, exception); + } + + @Override + public void resume(Object result) { + } + }; + } + + Object obj = method.invoke(scope, methodArgs); if (obj instanceof CompletableFuture) { CompletableFuture future = (CompletableFuture) obj; future.exceptionally(t -> { diff --git a/core/src/main/java/co/aikar/commands/kotlin/JavaContinuation.kt b/core/src/main/java/co/aikar/commands/kotlin/JavaContinuation.kt new file mode 100644 index 000000000..83b687b0f --- /dev/null +++ b/core/src/main/java/co/aikar/commands/kotlin/JavaContinuation.kt @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016-2020 Daniel Ennis (Aikar) - MIT License + * + * 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 co.aikar.commands.kotlin + +import kotlin.coroutines.Continuation +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext + +abstract class JavaContinuation : Continuation { + override val context: CoroutineContext + get() = EmptyCoroutineContext + + override fun resumeWith(result: Result) { + result.fold(::resume, ::resumeWithException) + } + + abstract fun resume(result: T) + abstract fun resumeWithException(exception: Throwable) +} \ No newline at end of file