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 ClassDescriptor fromClass = DescriptorUtils.getParentOfType(from, ClassDescriptor.class, false);
058 if (fromClass == null) return false;
059
060 ClassDescriptor whatClass;
061 // protected static class
062 if (what instanceof ClassDescriptor) {
063 DeclarationDescriptor containingDeclaration = what.getContainingDeclaration();
064 assert containingDeclaration instanceof ClassDescriptor : "Only static nested classes can have protected_static visibility";
065 whatClass = (ClassDescriptor) containingDeclaration;
066 }
067 // protected static function or property
068 else {
069 DeclarationDescriptor whatDeclarationDescriptor = what.getContainingDeclaration();
070 assert whatDeclarationDescriptor instanceof JavaClassStaticsPackageFragmentDescriptor
071 : "Only static declarations can have protected_static visibility";
072 whatClass = ((JavaClassStaticsPackageFragmentDescriptor) whatDeclarationDescriptor).getCorrespondingClass();
073 }
074
075 if (DescriptorUtils.isSubclass(fromClass, whatClass)) {
076 return true;
077 }
078 return isVisible(what, fromClass.getContainingDeclaration());
079 }
080
081 @Override
082 public String toString() {
083 return "protected/*protected static*/";
084 }
085
086 @NotNull
087 @Override
088 public Visibility normalize() {
089 return Visibilities.PROTECTED;
090 }
091 };
092
093 public static final Visibility PROTECTED_AND_PACKAGE = new Visibility("protected_and_package", false) {
094 @Override
095 protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
096 if (areInSamePackage(what, from)) {
097 return true;
098 }
099
100 ClassDescriptor whatClass = DescriptorUtils.getParentOfType(what, ClassDescriptor.class, false);
101 if (whatClass == null) return false;
102
103 ClassDescriptor fromClass = DescriptorUtils.getParentOfType(from, ClassDescriptor.class, false);
104 if (fromClass == null) return false;
105
106 if (DescriptorUtils.isSubclass(fromClass, whatClass)) {
107 return true;
108 }
109 return isVisible(what, fromClass.getContainingDeclaration());
110 }
111
112 @Override
113 protected Integer compareTo(@NotNull Visibility visibility) {
114 if (this == visibility) return 0;
115 if (visibility == Visibilities.INTERNAL) return null;
116 if (visibility == Visibilities.PRIVATE) return 1;
117 return -1;
118 }
119
120 @Override
121 public String toString() {
122 return "protected/*protected and package*/";
123 }
124
125 @NotNull
126 @Override
127 public Visibility normalize() {
128 return Visibilities.PROTECTED;
129 }
130 };
131
132 private static boolean areInSamePackage(@NotNull DeclarationDescriptor first, @NotNull DeclarationDescriptor second) {
133 PackageFragmentDescriptor whatPackage = getPackageStaticsAware(first);
134 PackageFragmentDescriptor fromPackage = getPackageStaticsAware(second);
135 return fromPackage != null && whatPackage != null && whatPackage.getFqName().equals(fromPackage.getFqName());
136 }
137
138 @Nullable
139 private static PackageFragmentDescriptor getPackageStaticsAware(@NotNull DeclarationDescriptor member) {
140 PackageFragmentDescriptor packageFragment = DescriptorUtils.getParentOfType(member, PackageFragmentDescriptor.class, false);
141 if (packageFragment instanceof JavaClassStaticsPackageFragmentDescriptor) {
142 ClassDescriptor classForPackage = ((JavaClassStaticsPackageFragmentDescriptor) packageFragment).getCorrespondingClass();
143 return DescriptorUtils.getParentOfType(classForPackage, PackageFragmentDescriptor.class, false);
144 }
145 return packageFragment;
146 }
147 }