2 * Copyright 2000-2016 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.
17 package com.intellij.util;
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;
29 public class VisibilityUtil {
30 @NonNls public static final String ESCALATE_VISIBILITY = "EscalateVisible";
31 private static final String[] visibilityModifiers = {
33 PsiModifier.PACKAGE_LOCAL,
34 PsiModifier.PROTECTED,
38 private VisibilityUtil() {
41 public static int compare(@PsiModifier.ModifierConstant String v1, @PsiModifier.ModifierConstant String v2) {
42 return ArrayUtilRt.find(visibilityModifiers, v2) - ArrayUtilRt.find(visibilityModifiers, v1);
45 @PsiModifier.ModifierConstant
46 public static String getHighestVisibility(@PsiModifier.ModifierConstant String v1, @PsiModifier.ModifierConstant String v2) {
47 return compare(v1, v2) < 0 ? v1 : v2;
50 public static void escalateVisibility(PsiMember modifierListOwner, PsiElement place) throws IncorrectOperationException {
51 final String visibilityModifier = getVisibilityModifier(modifierListOwner.getModifierList());
53 for (index = 0; index < visibilityModifiers.length; index++) {
54 String modifier = visibilityModifiers[index];
55 if(modifier.equals(visibilityModifier)) break;
57 for(;index < visibilityModifiers.length && !PsiUtil.isAccessible(modifierListOwner, place, null); index++) {
58 @PsiModifier.ModifierConstant String modifier = visibilityModifiers[index];
59 PsiUtil.setModifierProperty(modifierListOwner, modifier, true);
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);
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;
77 if (InheritanceUtil.isInheritorOrSelf(PsiTreeUtil.getParentOfType(place, PsiClass.class),
78 psiMethod.getContainingClass(), true)) {
79 return PsiModifier.PROTECTED;
81 return PsiModifier.PUBLIC;
84 @PsiModifier.ModifierConstant
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)) {
93 return PsiModifier.PACKAGE_LOCAL;
98 public static String getVisibilityString(@PsiModifier.ModifierConstant @NotNull String visibilityModifier) {
99 if(PsiModifier.PACKAGE_LOCAL.equals(visibilityModifier)) {
102 return visibilityModifier;
107 public static String getVisibilityStringToDisplay(@NotNull PsiMember member) {
108 if (member.hasModifierProperty(PsiModifier.PUBLIC)) {
109 return toPresentableText(PsiModifier.PUBLIC);
111 if (member.hasModifierProperty(PsiModifier.PROTECTED)) {
112 return toPresentableText(PsiModifier.PROTECTED);
114 if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
115 return toPresentableText(PsiModifier.PRIVATE);
117 return toPresentableText(PsiModifier.PACKAGE_LOCAL);
121 public static String toPresentableText(@PsiModifier.ModifierConstant @NotNull String modifier) {
122 return PsiBundle.visibilityPresentation(modifier);
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);
134 setVisibility(member.getModifierList(), newVisibility);
138 public static void setVisibility(@NotNull PsiModifierList modifierList, @PsiModifier.ModifierConstant @NotNull String newVisibility) throws IncorrectOperationException {
139 modifierList.setModifierProperty(newVisibility, true);
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);
150 setVisibility(member.getModifierList(), newVisibility);