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
.psi
.impl
.source
.resolve
;
22 import com
.intellij
.psi
.*;
23 import com
.intellij
.psi
.javadoc
.PsiDocComment
;
24 import com
.intellij
.psi
.scope
.PsiScopeProcessor
;
25 import com
.intellij
.psi
.util
.InheritanceUtil
;
26 import com
.intellij
.psi
.util
.PsiUtil
;
27 import com
.intellij
.psi
.xml
.XmlFile
;
28 import org
.jetbrains
.annotations
.NotNull
;
29 import org
.jetbrains
.annotations
.Nullable
;
31 public class JavaResolveUtil
{
32 public static PsiClass
getContextClass(PsiElement element
) {
33 PsiElement scope
= element
.getContext();
34 while (scope
!= null) {
35 if (scope
instanceof PsiClass
) return (PsiClass
)scope
;
36 scope
= scope
.getContext();
41 public static PsiElement
findParentContextOfClass(PsiElement element
, Class aClass
, boolean strict
){
42 PsiElement scope
= strict ? element
.getContext() : element
;
43 while(scope
!= null && !aClass
.isInstance(scope
)){
44 scope
= scope
.getContext();
49 public static boolean isAccessible(@NotNull PsiMember member
,
50 @Nullable final PsiClass memberClass
,
51 @Nullable PsiModifierList modifierList
,
52 @NotNull PsiElement place
,
53 @Nullable PsiClass accessObjectClass
,
54 @Nullable final PsiElement fileResolveScope
) {
55 if (modifierList
== null) return true;
56 final PsiFile placeContainingFile
= place
.getContainingFile();
57 final PsiManager manager
= member
.getManager();
58 if (placeContainingFile
instanceof JavaCodeFragment
) {
59 JavaCodeFragment fragment
= (JavaCodeFragment
)placeContainingFile
;
60 JavaCodeFragment
.VisibilityChecker visibilityChecker
= fragment
.getVisibilityChecker();
61 if (visibilityChecker
!= null) {
62 JavaCodeFragment
.VisibilityChecker
.Visibility visibility
= visibilityChecker
.isDeclarationVisible(member
, place
);
63 if (visibility
== JavaCodeFragment
.VisibilityChecker
.Visibility
.VISIBLE
) return true;
64 if (visibility
== JavaCodeFragment
.VisibilityChecker
.Visibility
.NOT_VISIBLE
) return false;
67 else if (placeContainingFile
instanceof XmlFile
&& !JspPsiUtil
.isInJspFile(placeContainingFile
)) return true;
68 // We don't care about access rights in javadoc
69 if (isInJavaDoc(place
)) return true;
71 if (accessObjectClass
!= null) {
72 if (!isAccessible(accessObjectClass
, accessObjectClass
.getContainingClass(), accessObjectClass
.getModifierList(), place
, null,
76 int effectiveAccessLevel
= PsiUtil
.getAccessLevel(modifierList
);
77 PsiFile file
= FileContextUtil
.getContextFile(place
); //TODO: implementation method!!!!
78 if (JspPsiUtil
.isInJspFile(file
) && JspPsiUtil
.isInJspFile(member
.getContainingFile())) return true;
79 if (file
instanceof XmlFile
&& !JspPsiUtil
.isInJspFile(file
)) return true;
80 if (effectiveAccessLevel
== PsiUtil
.ACCESS_LEVEL_PUBLIC
) {
83 if (effectiveAccessLevel
== PsiUtil
.ACCESS_LEVEL_PROTECTED
) {
84 if (JavaPsiFacade
.getInstance(manager
.getProject()).arePackagesTheSame(member
, place
)) return true;
85 if (memberClass
== null) return false;
86 for (PsiElement placeParent
= place
; placeParent
!= null; placeParent
= placeParent
.getContext()) {
87 if (placeParent
instanceof PsiClass
&& InheritanceUtil
.isInheritorOrSelf((PsiClass
)placeParent
, memberClass
, true)) {
88 if (member
instanceof PsiClass
|| modifierList
.hasModifierProperty(PsiModifier
.STATIC
)) return true;
89 if (accessObjectClass
== null || InheritanceUtil
.isInheritorOrSelf(accessObjectClass
, (PsiClass
)placeParent
, true)) return true;
92 //if (accessObjectClass != null && accessObjectClass.getManager().areElementsEquivalent(accessObjectClass, memberClass)) return true;
96 if (effectiveAccessLevel
== PsiUtil
.ACCESS_LEVEL_PRIVATE
) {
97 if (memberClass
== null) return true;
98 if (accessObjectClass
!= null) {
99 PsiClass topMemberClass
= getTopLevelClass(memberClass
, accessObjectClass
);
100 PsiClass topAccessClass
= getTopLevelClass(accessObjectClass
, memberClass
);
101 if (!manager
.areElementsEquivalent(topMemberClass
, topAccessClass
)) return false;
104 if (fileResolveScope
== null) {
105 PsiClass placeTopLevelClass
= getTopLevelClass(place
, null);
106 PsiClass memberTopLevelClass
= getTopLevelClass(memberClass
, null);
107 return manager
.areElementsEquivalent(placeTopLevelClass
, memberTopLevelClass
);
110 return fileResolveScope
instanceof PsiClass
&&
111 !((PsiClass
)fileResolveScope
).isInheritor(memberClass
, true);
114 if (!JavaPsiFacade
.getInstance(manager
.getProject()).arePackagesTheSame(member
, place
)) return false;
115 if (modifierList
.hasModifierProperty(PsiModifier
.STATIC
)) return true;
116 // maybe inheritance lead through package local class in other package ?
117 final PsiClass placeClass
= getContextClass(place
);
118 if (memberClass
== null || placeClass
== null) return true;
119 // check only classes since interface members are public, and if placeClass is interface,
120 // then its members are static, and cannot refer to nonstatic members of memberClass
121 if (memberClass
.isInterface() || placeClass
.isInterface()) return true;
122 PsiClass clazz
= accessObjectClass
!= null ?
124 placeClass
.getSuperClass(); //may start from super class
125 if (clazz
!= null && clazz
.isInheritor(memberClass
, true)) {
126 PsiClass superClass
= clazz
;
127 while (!manager
.areElementsEquivalent(superClass
, memberClass
)) {
128 if (superClass
== null || !JavaPsiFacade
.getInstance(manager
.getProject()).arePackagesTheSame(superClass
, memberClass
)) return false;
129 superClass
= superClass
.getSuperClass();
136 public static boolean isInJavaDoc(final PsiElement place
) {
137 PsiElement scope
= place
;
138 while(scope
!= null){
139 if (scope
instanceof PsiDocComment
) return true;
140 if (scope
instanceof PsiFile
) return false;
141 scope
= scope
.getContext();
146 private static PsiClass
getTopLevelClass(@NotNull PsiElement place
, PsiClass memberClass
) {
147 PsiClass lastClass
= null;
148 for (PsiElement placeParent
= place
; placeParent
!= null; placeParent
= placeParent
.getContext()) {
149 if (placeParent
instanceof PsiClass
&&
150 !(placeParent
instanceof PsiAnonymousClass
) &&
151 !(placeParent
instanceof PsiTypeParameter
)) {
152 PsiClass aClass
= (PsiClass
)placeParent
;
154 if (memberClass
!= null && aClass
.isInheritor(memberClass
, true)) return aClass
;
163 public static boolean processImplicitlyImportedPackages(final PsiScopeProcessor processor
,
164 final ResolveState state
,
165 final PsiElement place
,
166 PsiManager manager
) {
167 PsiPackage langPackage
= JavaPsiFacade
.getInstance(manager
.getProject()).findPackage("java.lang");
168 if (langPackage
!= null) {
169 if (!langPackage
.processDeclarations(processor
, state
, null, place
)) return false;
172 PsiPackage defaultPackage
= JavaPsiFacade
.getInstance(manager
.getProject()).findPackage("");
173 if (defaultPackage
!= null) {
174 if (!defaultPackage
.processDeclarations(processor
, state
, null, place
)) return false;