Cleanup: NotNull/Nullable
[idea/community.git] / java / java-psi-api / src / com / intellij / util / VisibilityUtil.java
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package com.intellij.util;
18
19 import com.intellij.openapi.project.Project;
20 import com.intellij.psi.*;
21 import com.intellij.psi.util.InheritanceUtil;
22 import com.intellij.psi.util.PsiTreeUtil;
23 import com.intellij.psi.util.PsiUtil;
24 import org.jetbrains.annotations.Nls;
25 import org.jetbrains.annotations.NonNls;
26 import org.jetbrains.annotations.NotNull;
27
28
29 public class VisibilityUtil  {
30   @NonNls public static final String ESCALATE_VISIBILITY = "EscalateVisible";
31   private static final String[] visibilityModifiers = {
32     PsiModifier.PRIVATE,
33     PsiModifier.PACKAGE_LOCAL,
34     PsiModifier.PROTECTED,
35     PsiModifier.PUBLIC
36   };
37
38   private VisibilityUtil() {
39   }
40
41   public static int compare(@PsiModifier.ModifierConstant String v1, @PsiModifier.ModifierConstant String v2) {
42     return ArrayUtilRt.find(visibilityModifiers, v2) - ArrayUtilRt.find(visibilityModifiers, v1);
43   }
44
45   @PsiModifier.ModifierConstant
46   public static String getHighestVisibility(@PsiModifier.ModifierConstant String v1, @PsiModifier.ModifierConstant String v2) {
47     return compare(v1, v2) < 0 ? v1 : v2;
48   }
49
50   public static void escalateVisibility(PsiMember modifierListOwner, PsiElement place) throws IncorrectOperationException {
51     final String visibilityModifier = getVisibilityModifier(modifierListOwner.getModifierList());
52     int index;
53     for (index = 0; index < visibilityModifiers.length; index++) {
54       String modifier = visibilityModifiers[index];
55       if(modifier.equals(visibilityModifier)) break;
56     }
57     for(;index < visibilityModifiers.length && !PsiUtil.isAccessible(modifierListOwner, place, null); index++) {
58       @PsiModifier.ModifierConstant String modifier = visibilityModifiers[index];
59       PsiUtil.setModifierProperty(modifierListOwner, modifier, true);
60     }
61   }
62
63   public static void escalateVisibility(PsiModifierList modifierList, PsiElement place) throws IncorrectOperationException {
64     final PsiElement parent = modifierList.getParent();
65     if (parent instanceof PsiMember) {
66       escalateVisibility((PsiMember)parent, place);
67     }
68   }
69
70   @PsiModifier.ModifierConstant
71   public static String getPossibleVisibility(final PsiMember psiMethod, final PsiElement place) {
72     Project project = psiMethod.getProject();
73     if (PsiUtil.isAccessible(project, psiMethod, place, null)) return getVisibilityModifier(psiMethod.getModifierList());
74     if (JavaPsiFacade.getInstance(project).arePackagesTheSame(psiMethod, place)) {
75       return PsiModifier.PACKAGE_LOCAL;
76     }
77     if (InheritanceUtil.isInheritorOrSelf(PsiTreeUtil.getParentOfType(place, PsiClass.class),
78                                           psiMethod.getContainingClass(), true)) {
79       return PsiModifier.PROTECTED;
80     }
81     return PsiModifier.PUBLIC;
82   }
83
84   @PsiModifier.ModifierConstant
85   @NotNull
86   public static String getVisibilityModifier(PsiModifierList list) {
87     if (list == null) return PsiModifier.PACKAGE_LOCAL;
88     for (@PsiModifier.ModifierConstant String modifier : visibilityModifiers) {
89       if (list.hasModifierProperty(modifier)) {
90         return modifier;
91       }
92     }
93     return PsiModifier.PACKAGE_LOCAL;
94   }
95
96   @NotNull
97   @NonNls
98   public static String getVisibilityString(@PsiModifier.ModifierConstant @NotNull String visibilityModifier) {
99     if(PsiModifier.PACKAGE_LOCAL.equals(visibilityModifier)) {
100       return "";
101     }
102     return visibilityModifier;
103   }
104
105   @Nls
106   @NotNull
107   public static String getVisibilityStringToDisplay(@NotNull PsiMember member) {
108     if (member.hasModifierProperty(PsiModifier.PUBLIC)) {
109       return toPresentableText(PsiModifier.PUBLIC);
110     }
111     if (member.hasModifierProperty(PsiModifier.PROTECTED)) {
112       return toPresentableText(PsiModifier.PROTECTED);
113     }
114     if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
115       return toPresentableText(PsiModifier.PRIVATE);
116     }
117     return toPresentableText(PsiModifier.PACKAGE_LOCAL);
118   }
119
120   @NotNull
121   public static String toPresentableText(@PsiModifier.ModifierConstant @NotNull String modifier) {
122     return PsiBundle.visibilityPresentation(modifier);
123   }
124
125   public static void fixVisibility(PsiElement[] elements, PsiMember member, @PsiModifier.ModifierConstant String newVisibility) {
126     if (newVisibility == null) return;
127     if (ESCALATE_VISIBILITY.equals(newVisibility)) {
128       for (PsiElement element : elements) {
129         if (element != null) {
130           escalateVisibility(member, element);
131         }
132       }
133     } else {
134        setVisibility(member.getModifierList(), newVisibility);
135     }
136   }
137
138   public static void setVisibility(@NotNull PsiModifierList modifierList, @PsiModifier.ModifierConstant @NotNull String newVisibility) throws IncorrectOperationException {
139     modifierList.setModifierProperty(newVisibility, true);
140   }
141
142   public static void fixVisibility(PsiExpression[] expressions, PsiMember member, String newVisibility) {
143     if (newVisibility == null) return;
144     if (ESCALATE_VISIBILITY.equals(newVisibility)) {
145       for (PsiExpression element : expressions) {
146         escalateVisibility(member, element);
147       }
148     }
149     else {
150       setVisibility(member.getModifierList(), newVisibility);
151     }
152   }
153 }