``Change visibility of field or method to lower access`` not working
AB-xdev opened this issue · 3 comments
AB-xdev commented
Change visibility of field or method to lower access
fails with
Caused by: java.lang.IllegalAccessError:
class com.intellij.codeInspection.visibility.CustomAccessCanBeTightenedInspection$MyVisitor tried to access
method 'int com.intellij.codeInspection.visibility.VisibilityInspection.getMinVisibilityLevel(com.intellij.psi.PsiMember)'
(com.intellij.codeInspection.visibility.CustomAccessCanBeTightenedInspection$MyVisitor is in unnamed module of loader
com.intellij.ide.plugins.cl.PluginClassLoader @2eed9be8;
com.intellij.codeInspection.visibility.VisibilityInspection is in unnamed module of loader
com.intellij.ide.plugins.cl.PluginClassLoader @5493c393)
...
Example code:
public class ABC
{
public void testCaller()
{
this.test();
}
public void test()
{
}
}
AB-xdev commented
AB-xdev commented
Okay so these different classloaders make it impossible to call package-private members.
Affected:
VisibilityInspection
int getMinVisibilityLevel(PsiMember)
boolean containsReferenceTo(PsiElement, PsiElement)
(static)
The only solution that I see is to either use reflection or make these members public.
AB-xdev commented
Reflection Git patch
diff --git a/src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java b/src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java
index eb473fb..b1028cc 100644
--- a/src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java
+++ b/src/main/java/com/intellij/codeInspection/visibility/CustomAccessCanBeTightenedInspection.java
@@ -31,9 +31,11 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.BiPredicate;
/**
* A public version of {@link AccessCanBeTightenedInspection}.
@@ -209,7 +211,20 @@ public class CustomAccessCanBeTightenedInspection extends AbstractBaseJavaLocalI
final PsiFile memberFile = member.getContainingFile();
Project project = memberFile.getProject();
- int level = myVisibilityInspection.getMinVisibilityLevel(member);
+ int level;
+ try {
+ final Method getMinVisibilityLevel = myVisibilityInspection.getClass()
+ .getDeclaredMethod("getMinVisibilityLevel", PsiMember.class);
+
+ getMinVisibilityLevel.setAccessible(true);
+
+ level = (int)getMinVisibilityLevel.invoke(myVisibilityInspection, member);
+ } catch (Exception e) {
+ Logger.getInstance(CustomAccessCanBeTightenedInspection.class)
+ .warn("Failed to invoke myVisibilityInspection", e);
+ throw new IllegalStateException("Failed to invoke myVisibilityInspection", e);
+ }
+
boolean entryPoint = myDeadCodeInspection.isEntryPoint(member) ||
member instanceof PsiField && (UnusedSymbolUtil.isImplicitWrite((PsiVariable)member) || UnusedSymbolUtil.isImplicitRead((PsiVariable)member));
if (entryPoint && level <= 0) {
@@ -310,9 +325,29 @@ public class CustomAccessCanBeTightenedInspection extends AbstractBaseJavaLocalI
// except when used in annotation:
// @Ann(value = C.VAL) class C { public static final String VAL = "xx"; }
// or in implements/extends clauses
- if (VisibilityInspection.containsReferenceTo(innerClass.getModifierList(), member) ||
- VisibilityInspection.containsReferenceTo(innerClass.getImplementsList(), member) ||
- VisibilityInspection.containsReferenceTo(innerClass.getExtendsList(), member)) {
+
+ final BiPredicate<PsiElement, PsiElement> containsReferenceTo;
+ try {
+ final Method m = VisibilityInspection.class
+ .getDeclaredMethod("containsReferenceTo", PsiElement.class, PsiElement.class);
+ m.setAccessible(true);
+
+ containsReferenceTo = (s, t) -> {
+ try {
+ return (boolean) m.invoke(null, s, t);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ };
+ } catch (final Exception ex) {
+ LOG.warn("Failed to make VisibilityInspection#containsReferenceTo accessible", ex);
+ throw new IllegalStateException("Failed to make VisibilityInspection#containsReferenceTo accessible", ex);
+ }
+
+
+ if (containsReferenceTo.test(innerClass.getModifierList(), member) ||
+ containsReferenceTo.test(innerClass.getImplementsList(), member) ||
+ containsReferenceTo.test(innerClass.getExtendsList(), member)) {
return suggestPackageLocal(member);
}