mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
access can be tightened for inner classes (IDEA-185790)
check enclosing instance for null qualifiers, if accessed via inheritance, then can't be private
This commit is contained in:
+7
-2
@@ -10,9 +10,11 @@ import com.intellij.codeInspection.inheritance.ImplicitSubclassProvider;
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
|
||||
import com.intellij.psi.util.ClassUtil;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.VisibilityUtil;
|
||||
@@ -255,7 +257,7 @@ class AccessCanBeTightenedInspection extends AbstractBaseJavaLocalInspectionTool
|
||||
PsiClass innerClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
|
||||
boolean isAbstractMember = member.hasModifierProperty(PsiModifier.ABSTRACT);
|
||||
if (memberClass != null && PsiTreeUtil.isAncestor(innerClass, memberClass, false) ||
|
||||
innerClass != null && PsiTreeUtil.isAncestor(memberClass, innerClass, false) && !innerClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
innerClass != null && PsiTreeUtil.isAncestor(memberClass, innerClass, false)) {
|
||||
// access from the same file can be via private
|
||||
// except when used in annotation:
|
||||
// @Ann(value = C.VAL) class C { public static final String VAL = "xx"; }
|
||||
@@ -301,7 +303,10 @@ class AccessCanBeTightenedInspection extends AbstractBaseJavaLocalInspectionTool
|
||||
|
||||
private boolean calledOnInheritor(@NotNull PsiElement element, PsiClass memberClass) {
|
||||
PsiExpression qualifier = getQualifier(element);
|
||||
if (qualifier == null) return false;
|
||||
if (qualifier == null) {
|
||||
PsiClass enclosingInstance = InheritanceUtil.findEnclosingInstanceInScope(memberClass, element, Condition.TRUE, true);
|
||||
return enclosingInstance != null && enclosingInstance != memberClass;
|
||||
}
|
||||
PsiClass qClass = PsiUtil.resolveClassInClassTypeOnly(qualifier.getType());
|
||||
return qClass != null && qClass.isInheritor(memberClass, true);
|
||||
}
|
||||
|
||||
@@ -142,31 +142,38 @@ public class InheritanceUtil {
|
||||
PsiElement scope,
|
||||
Condition<PsiClass> isSuperClassAccepted,
|
||||
boolean isTypeParamsAccepted) {
|
||||
return findEnclosingInstanceInScope(aClass, scope, isSuperClassAccepted, isTypeParamsAccepted) != null;
|
||||
}
|
||||
|
||||
public static PsiClass findEnclosingInstanceInScope(PsiClass aClass,
|
||||
PsiElement scope,
|
||||
Condition<PsiClass> isSuperClassAccepted,
|
||||
boolean isTypeParamsAccepted) {
|
||||
PsiManager manager = aClass.getManager();
|
||||
PsiElement place = scope;
|
||||
while (place != null && place != aClass && !(place instanceof PsiFile)) {
|
||||
while (place != null && !(place instanceof PsiFile)) {
|
||||
if (place instanceof PsiClass) {
|
||||
if (isSuperClassAccepted.value((PsiClass)place)) {
|
||||
if (isInheritorOrSelf((PsiClass)place, aClass, true)) return true;
|
||||
if (isInheritorOrSelf((PsiClass)place, aClass, true)) return (PsiClass)place;
|
||||
}
|
||||
else {
|
||||
if (manager.areElementsEquivalent(place, aClass)) return true;
|
||||
if (manager.areElementsEquivalent(place, aClass)) return aClass;
|
||||
}
|
||||
if (isTypeParamsAccepted && place instanceof PsiTypeParameter) {
|
||||
return true;
|
||||
return (PsiClass)place;
|
||||
}
|
||||
}
|
||||
if (place instanceof PsiModifierListOwner) {
|
||||
final PsiModifierList modifierList = ((PsiModifierListOwner)place).getModifierList();
|
||||
if (modifierList != null && modifierList.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
place = place.getParent();
|
||||
}
|
||||
return place == aClass;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static boolean processSuperTypes(@NotNull PsiType type, boolean includeSelf, @NotNull Processor<PsiType> processor) {
|
||||
if (includeSelf && !processor.process(type)) return false;
|
||||
return processSuperTypes(type, processor, new HashSet<>());
|
||||
|
||||
+7
@@ -224,6 +224,13 @@ public class AccessCanBeTightenedInspectionTest extends LightInspectionTestCase
|
||||
" return myElement;\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" <warning descr=\"Access can be private\">protected</warning> String myElement1;\n" +
|
||||
" class B1 {\n" +
|
||||
" @Override\n" +
|
||||
" public String toString() {\n" +
|
||||
" return myElement1;\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user