001 /*
002 * Copyright 2010-2013 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.jet.lang.resolve.java;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.annotations.Nullable;
021 import org.jetbrains.jet.lang.descriptors.*;
022 import org.jetbrains.jet.lang.resolve.DescriptorUtils;
023 import org.jetbrains.jet.lang.resolve.java.descriptor.JavaClassStaticsPackageFragmentDescriptor;
024
025 public class JavaVisibilities {
026 private JavaVisibilities() {
027 }
028
029 public static final Visibility PACKAGE_VISIBILITY = new Visibility("package", false) {
030 @Override
031 protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
032 return areInSamePackage(what, from);
033 }
034
035 @Override
036 protected Integer compareTo(@NotNull Visibility visibility) {
037 if (this == visibility) return 0;
038 if (visibility == Visibilities.PRIVATE) return 1;
039 return -1;
040 }
041
042 @Override
043 public String toString() {
044 return "public/*package*/";
045 }
046
047 @NotNull
048 @Override
049 public Visibility normalize() {
050 return Visibilities.INTERNAL;
051 }
052 };
053
054 public static final Visibility PROTECTED_STATIC_VISIBILITY = new Visibility("protected_static", false) {
055 @Override
056 protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
057 if (areInSamePackage(what, from)) {
058 return true;
059 }
060
061 ClassDescriptor fromClass = DescriptorUtils.getParentOfType(from, ClassDescriptor.class, false);
062 if (fromClass == null) return false;
063
064 ClassDescriptor whatClass;
065 // protected static class
066 if (what instanceof ClassDescriptor) {
067 DeclarationDescriptor containingDeclaration = what.getContainingDeclaration();
068 assert containingDeclaration instanceof ClassDescriptor : "Only static nested classes can have protected_static visibility";
069 whatClass = (ClassDescriptor) containingDeclaration;
070 }
071 // protected static function or property
072 else {
073 DeclarationDescriptor whatDeclarationDescriptor = what.getContainingDeclaration();
074 assert whatDeclarationDescriptor instanceof JavaClassStaticsPackageFragmentDescriptor
075 : "Only static declarations can have protected_static visibility";
076 whatClass = ((JavaClassStaticsPackageFragmentDescriptor) whatDeclarationDescriptor).getCorrespondingClass();
077 }
078
079 if (DescriptorUtils.isSubclass(fromClass, whatClass)) {
080 return true;
081 }
082 return isVisible(what, fromClass.getContainingDeclaration());
083 }
084
085 @Override
086 public String toString() {
087 return "protected/*protected static*/";
088 }
089
090 @NotNull
091 @Override
092 public Visibility normalize() {
093 return Visibilities.PROTECTED;
094 }
095 };
096
097 public static final Visibility PROTECTED_AND_PACKAGE = new Visibility("protected_and_package", false) {
098 @Override
099 protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
100 if (areInSamePackage(what, from)) {
101 return true;
102 }
103
104 ClassDescriptor whatClass = DescriptorUtils.getParentOfType(what, ClassDescriptor.class, false);
105 if (whatClass == null) return false;
106
107 ClassDescriptor fromClass = DescriptorUtils.getParentOfType(from, ClassDescriptor.class, false);
108 if (fromClass == null) return false;
109
110 if (DescriptorUtils.isSubclass(fromClass, whatClass)) {
111 return true;
112 }
113 return isVisible(what, fromClass.getContainingDeclaration());
114 }
115
116 @Override
117 protected Integer compareTo(@NotNull Visibility visibility) {
118 if (this == visibility) return 0;
119 if (visibility == Visibilities.INTERNAL) return null;
120 if (visibility == Visibilities.PRIVATE) return 1;
121 return -1;
122 }
123
124 @Override
125 public String toString() {
126 return "protected/*protected and package*/";
127 }
128
129 @NotNull
130 @Override
131 public Visibility normalize() {
132 return Visibilities.PROTECTED;
133 }
134 };
135
136 private static boolean areInSamePackage(@NotNull DeclarationDescriptor first, @NotNull DeclarationDescriptor second) {
137 PackageFragmentDescriptor whatPackage = getPackageStaticsAware(first);
138 PackageFragmentDescriptor fromPackage = getPackageStaticsAware(second);
139 return fromPackage != null && whatPackage != null && whatPackage.getFqName().equals(fromPackage.getFqName());
140 }
141
142 @Nullable
143 private static PackageFragmentDescriptor getPackageStaticsAware(@NotNull DeclarationDescriptor member) {
144 PackageFragmentDescriptor packageFragment = DescriptorUtils.getParentOfType(member, PackageFragmentDescriptor.class, false);
145 if (packageFragment instanceof JavaClassStaticsPackageFragmentDescriptor) {
146 ClassDescriptor classForPackage = ((JavaClassStaticsPackageFragmentDescriptor) packageFragment).getCorrespondingClass();
147 return DescriptorUtils.getParentOfType(classForPackage, PackageFragmentDescriptor.class, false);
148 }
149 return packageFragment;
150 }
151 }