001 /* 002 * Copyright 2010-2015 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.kotlin.load.java; 018 019 import org.jetbrains.annotations.NotNull; 020 import org.jetbrains.annotations.Nullable; 021 import org.jetbrains.kotlin.descriptors.*; 022 import org.jetbrains.kotlin.resolve.DescriptorUtils; 023 import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; 024 025 public class JavaVisibilities { 026 private JavaVisibilities() { 027 } 028 029 public static final Visibility PACKAGE_VISIBILITY = new Visibility("package", false) { 030 @Override 031 public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { 032 return areInSamePackage(what, from); 033 } 034 035 @Override 036 public boolean mustCheckInImports() { 037 return true; 038 } 039 040 @Override 041 protected Integer compareTo(@NotNull Visibility visibility) { 042 if (this == visibility) return 0; 043 if (Visibilities.isPrivate(visibility)) return 1; 044 return -1; 045 } 046 047 @NotNull 048 @Override 049 public String getDisplayName() { 050 return "public/*package*/"; 051 } 052 053 @NotNull 054 @Override 055 public Visibility normalize() { 056 return Visibilities.PROTECTED; 057 } 058 059 @NotNull 060 @Override 061 public EffectiveVisibility effectiveVisibility(@Nullable ClassDescriptor classDescriptor) { 062 return EffectiveVisibility.PackagePrivate.INSTANCE; 063 } 064 }; 065 066 public static final Visibility PROTECTED_STATIC_VISIBILITY = new Visibility("protected_static", true) { 067 @Override 068 public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { 069 if (areInSamePackage(what, from)) { 070 return true; 071 } 072 073 ClassDescriptor fromClass = DescriptorUtils.getParentOfType(from, ClassDescriptor.class, false); 074 if (fromClass == null) return false; 075 076 DeclarationDescriptor containingDeclaration = what.getContainingDeclaration(); 077 assert containingDeclaration instanceof ClassDescriptor : "Only class members can have protected_static visibility"; 078 ClassDescriptor whatClass = (ClassDescriptor) containingDeclaration; 079 080 if (DescriptorUtils.isSubclass(fromClass, whatClass)) { 081 return true; 082 } 083 return isVisible(receiver, what, fromClass.getContainingDeclaration()); 084 } 085 086 @Override 087 public boolean mustCheckInImports() { 088 return false; 089 } 090 091 @NotNull 092 @Override 093 public String getDisplayName() { 094 return "protected/*protected static*/"; 095 } 096 097 @NotNull 098 @Override 099 public Visibility normalize() { 100 return Visibilities.PROTECTED; 101 } 102 }; 103 104 public static final Visibility PROTECTED_AND_PACKAGE = new Visibility("protected_and_package", true) { 105 @Override 106 public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) { 107 if (areInSamePackage(what, from)) { 108 return true; 109 } 110 111 ClassDescriptor whatClass = DescriptorUtils.getParentOfType(what, ClassDescriptor.class, false); 112 if (whatClass == null) return false; 113 114 ClassDescriptor fromClass = DescriptorUtils.getParentOfType(from, ClassDescriptor.class, false); 115 if (fromClass == null) return false; 116 117 if (DescriptorUtils.isSubclass(fromClass, whatClass)) { 118 return true; 119 } 120 return isVisible(receiver, what, fromClass.getContainingDeclaration()); 121 } 122 123 @Override 124 public boolean mustCheckInImports() { 125 return false; 126 } 127 128 @Override 129 protected Integer compareTo(@NotNull Visibility visibility) { 130 if (this == visibility) return 0; 131 if (visibility == Visibilities.INTERNAL) return null; 132 if (Visibilities.isPrivate(visibility)) return 1; 133 return -1; 134 } 135 136 @NotNull 137 @Override 138 public String getDisplayName() { 139 return "protected/*protected and package*/"; 140 } 141 142 @NotNull 143 @Override 144 public Visibility normalize() { 145 return Visibilities.PROTECTED; 146 } 147 }; 148 149 private static boolean areInSamePackage(@NotNull DeclarationDescriptor first, @NotNull DeclarationDescriptor second) { 150 PackageFragmentDescriptor whatPackage = DescriptorUtils.getParentOfType(first, PackageFragmentDescriptor.class, false); 151 PackageFragmentDescriptor fromPackage = DescriptorUtils.getParentOfType(second, PackageFragmentDescriptor.class, false); 152 return fromPackage != null && whatPackage != null && whatPackage.getFqName().equals(fromPackage.getFqName()); 153 } 154 }