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.
16 package com
.intellij
.psi
.filters
.element
;
18 import com
.intellij
.psi
.PsiClass
;
19 import com
.intellij
.psi
.PsiClassType
;
20 import com
.intellij
.psi
.PsiElement
;
21 import com
.intellij
.psi
.PsiMethod
;
22 import com
.intellij
.psi
.filters
.ElementFilter
;
23 import com
.intellij
.psi
.filters
.position
.PositionElementFilter
;
24 import com
.intellij
.psi
.util
.MethodSignatureUtil
;
25 import com
.intellij
.reference
.SoftReference
;
28 * Created by IntelliJ IDEA.
32 * To change this template use Options | File Templates.
34 public class ExcludeDeclaredFilter
extends PositionElementFilter
{
35 public ExcludeDeclaredFilter(ElementFilter filter
){
39 public boolean isClassAcceptable(Class hintClass
){
41 //return PsiVariable.class.isAssignableFrom(hintClass);
44 SoftReference
<PsiElement
> myCachedVar
= new SoftReference
<PsiElement
>(null);
45 SoftReference
<PsiElement
> myCurrentContext
= new SoftReference
<PsiElement
>(null);
47 public boolean isAcceptable(Object element
, PsiElement context
){
48 PsiElement cachedVar
= context
;
50 if(myCurrentContext
.get() != context
){
51 myCurrentContext
= new SoftReference
<PsiElement
>(context
);
52 while(cachedVar
!= null && !(getFilter().isAcceptable(cachedVar
, cachedVar
.getContext())))
53 cachedVar
= cachedVar
.getContext();
54 myCachedVar
= new SoftReference
<PsiElement
>(cachedVar
);
57 if (element
instanceof PsiMethod
&& myCachedVar
.get() instanceof PsiMethod
) {
58 final PsiMethod currentMethod
= (PsiMethod
) element
;
59 final PsiMethod candidate
= (PsiMethod
) myCachedVar
.get();
60 return !candidate
.getManager().areElementsEquivalent(candidate
, currentMethod
) && !isOverridingMethod(currentMethod
, candidate
);
62 else if(element
instanceof PsiClassType
){
63 final PsiClass psiClass
= ((PsiClassType
)element
).resolve();
64 return isAcceptable(psiClass
, context
);
66 else if(context
!= null){
67 if(element
instanceof PsiElement
)
68 return !context
.getManager().areElementsEquivalent(myCachedVar
.get(), (PsiElement
)element
);
74 //TODO check exotic conditions like overriding method in package local class from class in other package
75 private static boolean isOverridingMethod(final PsiMethod method
, final PsiMethod candidate
) {
76 if (method
.getManager().areElementsEquivalent(method
, candidate
)) return false;
77 if (!MethodSignatureUtil
.areSignaturesEqual(method
,candidate
)) return false;
78 final PsiClass candidateContainingClass
= candidate
.getContainingClass();
79 return candidateContainingClass
.isInheritor(method
.getContainingClass(), true);