From 2899edd54987074f06e8fb57bb5665f338ccb284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9D=8F=E9=BB=91?= Date: Thu, 19 Sep 2019 14:46:48 +0800 Subject: [PATCH] + support kotlin companion object --- .../taboolib/compat/kotlin/CompatKotlin.java | 24 ++++++++++++++++++ .../module/inject/TFunctionLoader.java | 23 ++++++++++++++--- .../module/inject/TScheduleLoader.java | 25 +++++++++++-------- 3 files changed, 57 insertions(+), 15 deletions(-) create mode 100644 src/main/scala/io/izzel/taboolib/compat/kotlin/CompatKotlin.java diff --git a/src/main/scala/io/izzel/taboolib/compat/kotlin/CompatKotlin.java b/src/main/scala/io/izzel/taboolib/compat/kotlin/CompatKotlin.java new file mode 100644 index 0000000..a2c98f1 --- /dev/null +++ b/src/main/scala/io/izzel/taboolib/compat/kotlin/CompatKotlin.java @@ -0,0 +1,24 @@ +package io.izzel.taboolib.compat.kotlin; + +import io.izzel.taboolib.TabooLibAPI; +import io.izzel.taboolib.util.Reflection; + +/** + * @Author sky + * @Since 2019-09-19 14:27 + */ +public class CompatKotlin { + + public static boolean isCompanion(Class clazz) { + return clazz.getName().endsWith("$Companion"); + } + + public static Object getCompanion(Class clazz) { + try { + return Reflection.getValue(null, TabooLibAPI.getPluginBridge().getClass(clazz.getName().substring(0, clazz.getName().indexOf("$Companion"))), true, "Companion"); + } catch (Throwable t) { + t.printStackTrace(); + } + return null; + } +} diff --git a/src/main/scala/io/izzel/taboolib/module/inject/TFunctionLoader.java b/src/main/scala/io/izzel/taboolib/module/inject/TFunctionLoader.java index 0abe855..3c24028 100644 --- a/src/main/scala/io/izzel/taboolib/module/inject/TFunctionLoader.java +++ b/src/main/scala/io/izzel/taboolib/module/inject/TFunctionLoader.java @@ -1,6 +1,7 @@ package io.izzel.taboolib.module.inject; import io.izzel.taboolib.TabooLibLoader; +import io.izzel.taboolib.compat.kotlin.CompatKotlin; import io.izzel.taboolib.module.locale.logger.TLogger; import org.bukkit.plugin.Plugin; @@ -35,13 +36,20 @@ public class TFunctionLoader implements TabooLibLoader.Loader { if (pluginClass.isAnnotationPresent(TFunction.class)) { TFunction function = pluginClass.getAnnotation(TFunction.class); try { + Object instance = null; Method method = pluginClass.getDeclaredMethod(enable ? function.enable() : function.disable()); - if (!Modifier.isStatic(method.getModifiers())) { + if (CompatKotlin.isCompanion(pluginClass)) { + instance = CompatKotlin.getCompanion(pluginClass); + if (instance == null) { + TLogger.getGlobalLogger().error(method.getName() + " required @JvmStatic."); + return; + } + } else if (!Modifier.isStatic(method.getModifiers())) { TLogger.getGlobalLogger().error(method.getName() + " is not a static method."); return; } method.setAccessible(true); - method.invoke(null); + method.invoke(instance); } catch (NoSuchMethodException ignore) { } catch (Exception e) { e.printStackTrace(); @@ -53,12 +61,19 @@ public class TFunctionLoader implements TabooLibLoader.Loader { for (Method declaredMethod : pluginClass.getDeclaredMethods()) { if (declaredMethod.isAnnotationPresent(a)) { try { - if (!Modifier.isStatic(declaredMethod.getModifiers())) { + Object instance = null; + if (CompatKotlin.isCompanion(pluginClass)) { + instance = CompatKotlin.getCompanion(pluginClass); + if (instance == null) { + TLogger.getGlobalLogger().error(declaredMethod.getName() + " required @JvmStatic."); + return; + } + } else if (!Modifier.isStatic(declaredMethod.getModifiers())) { TLogger.getGlobalLogger().error(declaredMethod.getName() + " is not a static method."); return; } declaredMethod.setAccessible(true); - declaredMethod.invoke(null); + declaredMethod.invoke(instance); } catch (Throwable t) { t.printStackTrace(); } diff --git a/src/main/scala/io/izzel/taboolib/module/inject/TScheduleLoader.java b/src/main/scala/io/izzel/taboolib/module/inject/TScheduleLoader.java index 104e740..ad4af95 100644 --- a/src/main/scala/io/izzel/taboolib/module/inject/TScheduleLoader.java +++ b/src/main/scala/io/izzel/taboolib/module/inject/TScheduleLoader.java @@ -4,6 +4,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import io.izzel.taboolib.TabooLib; import io.izzel.taboolib.TabooLibLoader; +import io.izzel.taboolib.compat.kotlin.CompatKotlin; import io.izzel.taboolib.module.locale.logger.TLogger; import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitRunnable; @@ -43,36 +44,38 @@ public class TScheduleLoader implements TabooLibLoader.Loader { if (annotation == null) { continue; } - Object instance = pluginClass.equals(plugin.getClass()) ? plugin : null; - // 如果是非静态类型 - if (!Modifier.isStatic(method.getModifiers()) && instance == null) { - // 是否为主类 + Object[] instance = new Object[] {pluginClass.equals(plugin.getClass()) ? plugin : null}; + if (CompatKotlin.isCompanion(pluginClass)) { + instance[0] = CompatKotlin.getCompanion(pluginClass); + if (instance[0] == null) { + TLogger.getGlobalLogger().error(method.getName() + " required @JvmStatic."); + return; + } + } else if (!Modifier.isStatic(method.getModifiers()) && instance[0] == null) { TLogger.getGlobalLogger().error(method.getName() + " is not a static method."); continue; } - method.setAccessible(true); - // 如果是本插件 if (plugin.equals(TabooLib.getPlugin())) { run(plugin, new BukkitRunnable() { @Override public void run() { try { - method.invoke(instance); + method.setAccessible(true); + method.invoke(instance[0]); } catch (Throwable t) { t.printStackTrace(); } } }, annotation.delay(), annotation.period(), annotation.async()); - } - // 其他插件则添加到列队 - else { + } else { schedules.computeIfAbsent(plugin.getName(), n -> Lists.newArrayList()).add(new TScheduleData(annotation, new BukkitRunnable() { @Override public void run() { try { - method.invoke(instance); + method.setAccessible(true); + method.invoke(instance[0]); } catch (Throwable t) { t.printStackTrace(); }