update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / psi / impl / source / resolve / JavaResolveUtil.java
blobc23d3ce2de4466db673f8a42849df9a9bc76ba0f
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.
18 * @author max
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();
38 return null;
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();
46 return scope;
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,
73 null)) return false;
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) {
81 return true;
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;
94 return false;
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);
109 else {
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 ?
123 accessObjectClass :
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();
133 return true;
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();
143 return false;
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;
156 lastClass = aClass;
160 return lastClass;
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;
176 return true;