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        @NotNull
030        public static final Visibility PACKAGE_VISIBILITY = new Visibility("package", false) {
031            @Override
032            public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
033                return areInSamePackage(what, from);
034            }
035    
036            @Override
037            public boolean mustCheckInImports() {
038                return true;
039            }
040    
041            @Override
042            protected Integer compareTo(@NotNull Visibility visibility) {
043                if (this == visibility) return 0;
044                if (Visibilities.isPrivate(visibility)) return 1;
045                return -1;
046            }
047    
048            @NotNull
049            @Override
050            public String getDisplayName() {
051                return "public/*package*/";
052            }
053    
054            @NotNull
055            @Override
056            public Visibility normalize() {
057                return Visibilities.PROTECTED;
058            }
059    
060            @NotNull
061            @Override
062            public EffectiveVisibility effectiveVisibility(@NotNull DeclarationDescriptor classDescriptor, boolean checkPublishedApi) {
063                return EffectiveVisibility.PackagePrivate.INSTANCE;
064            }
065        };
066    
067        @NotNull
068        public static final Visibility PROTECTED_STATIC_VISIBILITY = new Visibility("protected_static", true) {
069            @Override
070            public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
071                return isVisibleForProtectedAndPackage(receiver, what, from);
072            }
073    
074            @Override
075            public boolean mustCheckInImports() {
076                return false;
077            }
078    
079            @NotNull
080            @Override
081            public String getDisplayName() {
082                return "protected/*protected static*/";
083            }
084    
085            @NotNull
086            @Override
087            public Visibility normalize() {
088                return Visibilities.PROTECTED;
089            }
090        };
091    
092        @NotNull
093        public static final Visibility PROTECTED_AND_PACKAGE = new Visibility("protected_and_package", true) {
094            @Override
095            public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
096                return isVisibleForProtectedAndPackage(receiver, what, from);
097            }
098    
099            @Override
100            public boolean mustCheckInImports() {
101                return false;
102            }
103    
104            @Override
105            protected Integer compareTo(@NotNull Visibility visibility) {
106                if (this == visibility) return 0;
107                if (visibility == Visibilities.INTERNAL) return null;
108                if (Visibilities.isPrivate(visibility)) return 1;
109                return -1;
110            }
111    
112            @NotNull
113            @Override
114            public String getDisplayName() {
115                return "protected/*protected and package*/";
116            }
117    
118            @NotNull
119            @Override
120            public Visibility normalize() {
121                return Visibilities.PROTECTED;
122            }
123        };
124    
125        private static boolean isVisibleForProtectedAndPackage(
126                @Nullable ReceiverValue receiver,
127                @NotNull DeclarationDescriptorWithVisibility what,
128                @NotNull DeclarationDescriptor from
129        ) {
130            if (areInSamePackage(DescriptorUtils.unwrapFakeOverrideToAnyDeclaration(what), from)) {
131                return true;
132            }
133    
134            return Visibilities.PROTECTED.isVisible(receiver, what, from);
135        }
136    
137        private static boolean areInSamePackage(@NotNull DeclarationDescriptor first, @NotNull DeclarationDescriptor second) {
138            PackageFragmentDescriptor whatPackage = DescriptorUtils.getParentOfType(first, PackageFragmentDescriptor.class, false);
139            PackageFragmentDescriptor fromPackage = DescriptorUtils.getParentOfType(second, PackageFragmentDescriptor.class, false);
140            return fromPackage != null && whatPackage != null && whatPackage.getFqName().equals(fromPackage.getFqName());
141        }
142    }