|
19 | 19 | import com.btk5h.skriptmirror.ImportNotFoundException; |
20 | 20 | import com.btk5h.skriptmirror.JavaCallException; |
21 | 21 | import com.btk5h.skriptmirror.JavaType; |
22 | | -import com.btk5h.skriptmirror.util.LRUCache; |
23 | 22 | import com.btk5h.skriptmirror.Null; |
24 | 23 | import com.btk5h.skriptmirror.ObjectWrapper; |
25 | 24 | import com.btk5h.skriptmirror.skript.custom.CustomImport; |
26 | 25 | import com.btk5h.skriptmirror.util.JavaUtil; |
| 26 | +import com.btk5h.skriptmirror.util.LRUCache; |
27 | 27 | import com.btk5h.skriptmirror.util.SkriptMirrorUtil; |
28 | 28 | import com.btk5h.skriptmirror.util.SkriptUtil; |
29 | 29 | import com.btk5h.skriptmirror.util.StringSimilarity; |
|
42 | 42 | import java.lang.reflect.Executable; |
43 | 43 | import java.lang.reflect.Member; |
44 | 44 | import java.lang.reflect.Method; |
| 45 | +import java.lang.reflect.Modifier; |
45 | 46 | import java.lang.reflect.Parameter; |
46 | 47 | import java.util.ArrayList; |
47 | 48 | import java.util.Arrays; |
@@ -370,7 +371,7 @@ private Collection<MethodHandle> createCallSite(Descriptor descriptor) { |
370 | 371 |
|
371 | 372 | JavaUtil.fields(javaClass) |
372 | 373 | .filter(f -> f.getName().equals(descriptor.getName())) |
373 | | - .map(ExprJavaCall::setAccessible) |
| 374 | + .map(ExprJavaCall::getAccess) |
374 | 375 | .filter(Objects::nonNull) |
375 | 376 | .forEach(field -> { |
376 | 377 | try { |
@@ -406,14 +407,14 @@ private Collection<MethodHandle> createCallSite(Descriptor descriptor) { |
406 | 407 | } |
407 | 408 |
|
408 | 409 | return methodStream |
409 | | - .map(ExprJavaCall::setAccessible) |
| 410 | + .map(ExprJavaCall::getAccess) |
410 | 411 | .filter(Objects::nonNull) |
411 | 412 | .map(JavaUtil.propagateErrors(LOOKUP::unreflect)) |
412 | 413 | .filter(Objects::nonNull) |
413 | 414 | .collect(Collectors.toList()); |
414 | 415 | case CONSTRUCTOR: |
415 | 416 | return JavaUtil.constructors(javaClass) |
416 | | - .map(ExprJavaCall::setAccessible) |
| 417 | + .map(ExprJavaCall::getAccess) |
417 | 418 | .filter(Objects::nonNull) |
418 | 419 | .map(JavaUtil.propagateErrors(LOOKUP::unreflectConstructor)) |
419 | 420 | .filter(Objects::nonNull) |
@@ -832,20 +833,60 @@ private static String argumentsToString(Object... arguments) { |
832 | 833 | .collect(Collectors.joining(", ")); |
833 | 834 | } |
834 | 835 |
|
| 836 | + @SuppressWarnings("unchecked") |
835 | 837 | @Nullable |
836 | | - private static <T extends AccessibleObject> T setAccessible(T t) { |
| 838 | + private static <T extends AccessibleObject> T getAccess(T member) { |
837 | 839 | try { |
838 | | - t.setAccessible(true); |
839 | | - return t; |
| 840 | + member.setAccessible(true); |
| 841 | + return member; |
840 | 842 | } catch (RuntimeException e) { |
841 | 843 | // InaccessibleObjectException exists in Java 9+ only |
842 | 844 | if (e instanceof SecurityException || e.getClass().getName().equals("java.lang.reflect.InaccessibleObjectException")) { |
843 | | - return null; |
| 845 | + Member superMember = getSuperMember((Member) member); |
| 846 | + return superMember != null ? getAccess((T) superMember) : null; |
844 | 847 | } |
845 | 848 | throw e; |
846 | 849 | } |
847 | 850 | } |
848 | 851 |
|
| 852 | + @Nullable |
| 853 | + private static Member getSuperMember(Member member) { |
| 854 | + if (!(member instanceof Executable)) |
| 855 | + return null; |
| 856 | + Executable executable = (Executable) member; |
| 857 | + if ((executable.getModifiers() & Modifier.STATIC) != 0) |
| 858 | + return null; |
| 859 | + |
| 860 | + return getSuperMember(executable, executable.getDeclaringClass()); |
| 861 | + } |
| 862 | + |
| 863 | + @Nullable |
| 864 | + private static Executable getSuperMember(Executable executable, Class<?> declaringClass) { |
| 865 | + List<Executable> executables = new ArrayList<>(); |
| 866 | + executables.addAll(Arrays.asList(declaringClass.getDeclaredMethods())); |
| 867 | + executables.addAll(Arrays.asList(declaringClass.getDeclaredConstructors())); |
| 868 | + |
| 869 | + if (executable.getDeclaringClass() != declaringClass) |
| 870 | + for (Executable loopExecutable : executables) { |
| 871 | + if (executable.getName().equals(loopExecutable.getName()) |
| 872 | + && Arrays.equals(executable.getParameterTypes(), loopExecutable.getParameterTypes())) { |
| 873 | + return loopExecutable; |
| 874 | + } |
| 875 | + } |
| 876 | + |
| 877 | + List<Class<?>> superClasses = new ArrayList<>(); |
| 878 | + superClasses.add(declaringClass.getSuperclass()); |
| 879 | + superClasses.addAll(Arrays.asList(declaringClass.getInterfaces())); |
| 880 | + |
| 881 | + for (Class<?> superClass : superClasses) { |
| 882 | + Executable superExecutable = getSuperMember(executable, superClass); |
| 883 | + if (superExecutable != null) |
| 884 | + return superExecutable; |
| 885 | + } |
| 886 | + |
| 887 | + return null; |
| 888 | + } |
| 889 | + |
849 | 890 | @Override |
850 | 891 | public String toString(Event e, boolean debug) { |
851 | 892 | switch (type) { |
|
0 commit comments