diff --git a/common/src/main/java/me/shedaniel/architectury/PlatformMethods.java b/common/src/main/java/me/shedaniel/architectury/PlatformMethods.java index 7c2ac7a1..4aa3e21f 100644 --- a/common/src/main/java/me/shedaniel/architectury/PlatformMethods.java +++ b/common/src/main/java/me/shedaniel/architectury/PlatformMethods.java @@ -19,20 +19,36 @@ package me.shedaniel.architectury; +import me.shedaniel.architectury.utils.PlatformExpectedError; import org.jetbrains.annotations.ApiStatus; -import java.lang.invoke.CallSite; -import java.lang.invoke.ConstantCallSite; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; +import java.lang.invoke.*; @ApiStatus.Internal public class PlatformMethods { - public static CallSite platform(MethodHandles.Lookup lookup, String name, MethodType type) - throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException { + public static CallSite platform(MethodHandles.Lookup lookup, String name, MethodType type) { Class lookupClass = lookup.lookupClass(); String lookupType = lookupClass.getName().replace("$", "") + "Impl"; - Class newClass = Class.forName(lookupType.substring(0, lookupType.lastIndexOf('.')) + "." + Architectury.getModLoader() + "." + lookupType.substring(lookupType.lastIndexOf('.') + 1), false, lookupClass.getClassLoader()); - return new ConstantCallSite(lookup.findStatic(newClass, name, type)); + + String platformExpectedClass = lookupType.substring(0, lookupType.lastIndexOf('.')) + "." + Architectury.getModLoader() + "." + + lookupType.substring(lookupType.lastIndexOf('.') + 1); + Class newClass; + try { + newClass = Class.forName(platformExpectedClass, false, lookupClass.getClassLoader()); + } catch (ClassNotFoundException exception) { + throw new PlatformExpectedError(lookupClass.getName() + "#" + name + " expected platform implementation in " + platformExpectedClass + + "#" + name + ", but the class doesn't exist!", exception); + } + MethodHandle platformMethod; + try { + platformMethod = lookup.findStatic(newClass, name, type); + } catch (NoSuchMethodException exception) { + throw new PlatformExpectedError(lookupClass.getName() + "#" + name + " expected platform implementation in " + platformExpectedClass + + "#" + name + ", but the method doesn't exist!", exception); + } catch (IllegalAccessException exception) { + throw new PlatformExpectedError(lookupClass.getName() + "#" + name + " expected platform implementation in " + platformExpectedClass + + "#" + name + ", but the method's modifier doesn't match the access requirements!", exception); + } + return new ConstantCallSite(platformMethod); } } diff --git a/common/src/main/java/me/shedaniel/architectury/utils/PlatformExpectedError.java b/common/src/main/java/me/shedaniel/architectury/utils/PlatformExpectedError.java new file mode 100644 index 00000000..a35aef0d --- /dev/null +++ b/common/src/main/java/me/shedaniel/architectury/utils/PlatformExpectedError.java @@ -0,0 +1,41 @@ +/* + * This file is part of architectury. + * Copyright (C) 2020 shedaniel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package me.shedaniel.architectury.utils; + +public class PlatformExpectedError extends Error { + public PlatformExpectedError() { + } + + public PlatformExpectedError(String message) { + super(message); + } + + public PlatformExpectedError(String message, Throwable cause) { + super(message, cause); + } + + public PlatformExpectedError(Throwable cause) { + super(cause); + } + + public PlatformExpectedError(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +}