good code is red (in presence of raw overriding)
[fedora-idea.git] / java / openapi / src / com / intellij / codeInsight / ClassUtil.java
blobe7b0fbf6849b406e5f87631ba5d174dbb6bce611
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 /**
18 * @author Alexey
20 package com.intellij.codeInsight;
22 import com.intellij.psi.*;
23 import gnu.trove.THashSet;
24 import org.jetbrains.annotations.NotNull;
26 import java.util.List;
27 import java.util.Set;
29 public class ClassUtil {
30 public static PsiMethod getAnyAbstractMethod(@NotNull PsiClass aClass) {
31 PsiMethod methodToImplement = getAnyMethodToImplement(aClass);
32 if (methodToImplement != null) {
33 return methodToImplement;
35 PsiMethod[] methods = aClass.getMethods();
36 for (PsiMethod method : methods) {
37 if (method.hasModifierProperty(PsiModifier.ABSTRACT)) return method;
40 return null;
43 public static PsiMethod getAnyMethodToImplement(PsiClass aClass) {
44 Set<PsiMethod> alreadyImplemented = new THashSet<PsiMethod>();
45 for (HierarchicalMethodSignature signatureHierarchical : aClass.getVisibleSignatures()) {
46 for (PsiMethod superS : signatureHierarchical.getMethod().findSuperMethods()) {
47 add(superS, alreadyImplemented);
50 PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(aClass.getProject()).getResolveHelper();
51 for (HierarchicalMethodSignature signatureHierarchical : aClass.getVisibleSignatures()) {
52 PsiMethod method = signatureHierarchical.getMethod();
53 PsiClass containingClass = method.getContainingClass();
54 if (containingClass == null) {
55 continue;
57 if (!aClass.equals(containingClass)
58 && method.hasModifierProperty(PsiModifier.ABSTRACT)
59 && !method.hasModifierProperty(PsiModifier.STATIC)
60 && !method.hasModifierProperty(PsiModifier.PRIVATE)
61 && !alreadyImplemented.contains(method)) {
62 return method;
64 final List<HierarchicalMethodSignature> superSignatures = signatureHierarchical.getSuperSignatures();
65 for (HierarchicalMethodSignature superSignatureHierarchical : superSignatures) {
66 final PsiMethod superMethod = superSignatureHierarchical.getMethod();
67 if (superMethod.hasModifierProperty(PsiModifier.ABSTRACT) && !resolveHelper.isAccessible(superMethod, method, null)) {
68 return superMethod;
73 return checkPackageLocalInSuperClass(aClass);
76 private static PsiMethod checkPackageLocalInSuperClass(PsiClass aClass) {
77 // super class can have package local sbstract methods not accessible for overriding
78 PsiClass superClass = aClass.getSuperClass();
79 if (superClass == null) return null;
80 if ("java.lang.Object".equals(aClass.getQualifiedName())) return null;
81 if (JavaPsiFacade.getInstance(aClass.getProject()).arePackagesTheSame(aClass, superClass)) return null;
83 for (HierarchicalMethodSignature methodSignature : superClass.getVisibleSignatures()) {
84 PsiMethod method = methodSignature.getMethod();
85 if (method.hasModifierProperty(PsiModifier.ABSTRACT) && method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) return method;
87 return null;
90 private static boolean add(PsiMethod method, Set<PsiMethod> alreadyImplemented) {
91 boolean already = alreadyImplemented.add(method);
93 for (PsiMethod superSig : method.findSuperMethods()) {
94 already &= add(superSig, alreadyImplemented);
96 return already;