Use hierarchical method signature to find super methods (IDEA-CR-48492)

GitOrigin-RevId: aade4d1be9f064bef096e9be2a2c228184aa0686
This commit is contained in:
Tagir Valeev
2019-07-02 06:52:16 +03:00
committed by intellij-monorepo-bot
parent 5907d8eed1
commit 6cc1a148ac
2 changed files with 39 additions and 5 deletions
@@ -3,6 +3,7 @@ package com.siyeh.ipp.modifiers;
import com.intellij.psi.PsiKeyword;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiModifierList;
import com.intellij.psi.PsiModifierListOwner;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
@@ -74,6 +75,23 @@ enum AccessModifier {
}
}
public static AccessModifier fromModifierList(@NotNull PsiModifierList modifierList) {
if (modifierList.hasModifierProperty(PsiModifier.PRIVATE)) {
return PRIVATE;
}
if (modifierList.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) {
return PACKAGE_LOCAL;
}
if (modifierList.hasModifierProperty(PsiModifier.PROTECTED)) {
return PROTECTED;
}
return PUBLIC;
}
public boolean isWeaker(@NotNull AccessModifier other) {
return ordinal() < other.ordinal();
}
@Override
public String toString() {
return this == PACKAGE_LOCAL ? "package-private" : toPsiModifier();
@@ -36,6 +36,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.BaseRefactoringProcessor;
@@ -132,11 +133,7 @@ public class ChangeModifierIntention extends BaseElementAtCaretIntentionAction {
return PUBLIC_PRIVATE;
}
}
PsiMethod[] superMethods = ((PsiMethod)member).findSuperMethods(false);
AccessModifier minAccess = superMethods.length == 0 ? AccessModifier.PRIVATE :
StreamEx.of(AccessModifier.values())
.filter(mod -> Stream.of(superMethods).anyMatch(m -> mod.hasModifier(m)))
.findFirst().orElse(AccessModifier.PRIVATE);
AccessModifier minAccess = getMinAccess((PsiMethod)member);
if (minAccess != AccessModifier.PRIVATE) {
return ContainerUtil.filter(ALL_MODIFIERS, mod -> mod.compareTo(minAccess) <= 0);
}
@@ -150,6 +147,25 @@ public class ChangeModifierIntention extends BaseElementAtCaretIntentionAction {
return Collections.emptyList();
}
@NotNull
private static AccessModifier getMinAccess(PsiMethod method) {
if (method.isConstructor() || method.hasModifierProperty(PsiModifier.STATIC)) return AccessModifier.PRIVATE;
HierarchicalMethodSignature signature = method.getHierarchicalMethodSignature();
AccessModifier lowest = AccessModifier.PRIVATE;
for (HierarchicalMethodSignature superSignature : signature.getSuperSignatures()) {
PsiMethod superMethod = superSignature.getMethod();
AccessModifier current = AccessModifier.fromModifierList(superMethod.getModifierList());
if (!current.isWeaker(lowest)) continue;
if (method.hasModifierProperty(PsiModifier.ABSTRACT) && !MethodSignatureUtil.isSuperMethod(superMethod, method)) continue;
if (!PsiUtil.isAccessible(method.getProject(), superMethod, method, null)) continue;
lowest = current;
if (lowest == AccessModifier.PUBLIC) {
break;
}
}
return lowest;
}
@Nullable
@Override
public PsiElement getElementToMakeWritable(@NotNull PsiFile currentFile) {