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.
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
;
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
;
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) {
57 if (!aClass
.equals(containingClass
)
58 && method
.hasModifierProperty(PsiModifier
.ABSTRACT
)
59 && !method
.hasModifierProperty(PsiModifier
.STATIC
)
60 && !method
.hasModifierProperty(PsiModifier
.PRIVATE
)
61 && !alreadyImplemented
.contains(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)) {
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
;
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
);