[java-generation] IDEA-372740 ConcurrentMap implementation must override putIfAbsent, but that method is not in the Override Methods screen, nor Implement Methods

GitOrigin-RevId: d37733578b8cc097b034f1c729abcdbb12c7015c
This commit is contained in:
Mikhail Pyltsin
2025-09-23 14:56:40 +00:00
committed by intellij-monorepo-bot
parent 2e092f9619
commit 1dc66aa0e3
6 changed files with 177 additions and 0 deletions
@@ -39,6 +39,7 @@ public class OverrideImplementExploreUtil {
PsiUtilCore.ensureValid(aClass);
Collection<HierarchicalMethodSignature> allMethodSigs = aClass.getVisibleSignatures();
allMethodSigs = deleteShadowed(allMethodSigs);
PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(aClass.getProject()).getResolveHelper();
Map<MethodSignature, PsiMethod> abstracts = new LinkedHashMap<>();
Map<MethodSignature, PsiMethod> finals = new LinkedHashMap<>();
@@ -106,6 +107,46 @@ public class OverrideImplementExploreUtil {
return result;
}
/**
* {@link PsiClass#getVisibleSignatures()} can return shadowed methods to highlight them (if there is a compilation error),
* but it is necessary to get rid of them, because otherwise some methods can be missed to implement.
*/
private static @NotNull Collection<HierarchicalMethodSignature> deleteShadowed(@NotNull Collection<HierarchicalMethodSignature> sigs) {
ArrayList<HierarchicalMethodSignature> signatures = new ArrayList<>();
HashMap<String, List<HierarchicalMethodSignature>> nameToSignature = new HashMap<>();
for (HierarchicalMethodSignature signature : sigs) {
String name = signature.getMethod().getName();
List<HierarchicalMethodSignature> previousSignatures = nameToSignature.get(name);
if (previousSignatures == null) {
List<HierarchicalMethodSignature> list = new ArrayList<>();
list.add(signature);
nameToSignature.put(name, list);
signatures.add(signature);
continue;
}
boolean addToList = true;
for (HierarchicalMethodSignature previousSignature : previousSignatures) {
if (!MethodSignatureUtil.areSignaturesErasureEqual(signature, previousSignature)) continue;
PsiClass containingClass = signature.getMethod().getContainingClass();
PsiClass previousContainingClass = previousSignature.getMethod().getContainingClass();
if (containingClass == null || previousContainingClass == null ||
containingClass.getManager().areElementsEquivalent(containingClass, previousContainingClass)) {
continue;
}
if (containingClass.isInheritor(previousContainingClass, true)) {
signatures.remove(previousSignature);
}
else if (previousContainingClass.isInheritor(containingClass, true)) {
addToList = false;
break;
}
}
previousSignatures.add(signature);
if (addToList) signatures.add(signature);
}
return signatures;
}
private static boolean isDefaultMethod(@NotNull PsiClass aClass, @NotNull PsiMethod method) {
return method.hasModifierProperty(PsiModifier.DEFAULT) && PsiUtil.isAvailable(JavaFeature.EXTENSION_METHODS, aClass);
}