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.scope;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.jet.lang.descriptors.*;
021    import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor;
022    import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils;
023    import org.jetbrains.jet.lang.resolve.java.resolver.JavaFunctionResolver;
024    import org.jetbrains.jet.lang.resolve.java.resolver.JavaMemberResolver;
025    import org.jetbrains.jet.lang.resolve.java.resolver.ProgressChecker;
026    import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
027    import org.jetbrains.jet.lang.resolve.java.structure.JavaPackage;
028    import org.jetbrains.jet.lang.resolve.name.FqName;
029    import org.jetbrains.jet.lang.resolve.name.Name;
030    
031    import java.util.Collection;
032    import java.util.Collections;
033    import java.util.HashSet;
034    import java.util.Set;
035    
036    import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES;
037    import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN_SOURCES;
038    
039    public final class JavaPackageScope extends JavaBaseScope {
040        @NotNull
041        private final JavaPackage javaPackage;
042        @NotNull
043        private final FqName packageFQN;
044    
045        public JavaPackageScope(
046                @NotNull NamespaceDescriptor descriptor,
047                @NotNull JavaPackage javaPackage,
048                @NotNull FqName packageFQN,
049                @NotNull JavaMemberResolver memberResolver
050        ) {
051            super(descriptor, memberResolver, MembersProvider.forPackage(javaPackage));
052            this.javaPackage = javaPackage;
053            this.packageFQN = packageFQN;
054        }
055    
056        @Override
057        public ClassifierDescriptor getClassifier(@NotNull Name name) {
058            ClassDescriptor classDescriptor = memberResolver.resolveClass(packageFQN.child(name), IGNORE_KOTLIN_SOURCES);
059            if (classDescriptor == null || classDescriptor.getKind().isSingleton()) {
060                return null;
061            }
062            return classDescriptor;
063        }
064    
065        @Override
066        public ClassDescriptor getObjectDescriptor(@NotNull Name name) {
067            ClassDescriptor classDescriptor = memberResolver.resolveClass(packageFQN.child(name), IGNORE_KOTLIN_SOURCES);
068            if (classDescriptor != null && classDescriptor.getKind().isSingleton()) {
069                return classDescriptor;
070            }
071            return null;
072        }
073    
074        @Override
075        public NamespaceDescriptor getNamespace(@NotNull Name name) {
076            return memberResolver.resolveNamespace(packageFQN.child(name), INCLUDE_KOTLIN_SOURCES);
077        }
078    
079        @NotNull
080        @Override
081        protected Collection<DeclarationDescriptor> computeAllDescriptors() {
082            Collection<DeclarationDescriptor> result = super.computeAllDescriptors();
083            result.addAll(computeAllPackageDeclarations());
084            return result;
085        }
086    
087        @NotNull
088        private Collection<DeclarationDescriptor> computeAllPackageDeclarations() {
089            Collection<DeclarationDescriptor> result = new HashSet<DeclarationDescriptor>();
090    
091            for (JavaPackage subPackage : javaPackage.getSubPackages()) {
092                NamespaceDescriptor childNs = memberResolver.resolveNamespace(subPackage.getFqName(), IGNORE_KOTLIN_SOURCES);
093                if (childNs != null) {
094                    result.add(childNs);
095                }
096            }
097    
098            for (JavaClass javaClass : DescriptorResolverUtils.getClassesInPackage(javaPackage)) {
099                if (DescriptorResolverUtils.isCompiledKotlinPackageClass(javaClass)) continue;
100    
101                if (javaClass.getOriginKind() == JavaClass.OriginKind.KOTLIN_LIGHT_CLASS) continue;
102    
103                if (javaClass.getVisibility() == Visibilities.PRIVATE) continue;
104    
105                ProgressChecker.getInstance().checkCanceled();
106    
107                FqName fqName = javaClass.getFqName();
108                if (fqName == null) continue;
109    
110                ClassDescriptor classDescriptor = memberResolver.resolveClass(fqName, IGNORE_KOTLIN_SOURCES);
111                if (classDescriptor != null) {
112                    result.add(classDescriptor);
113                }
114    
115                NamespaceDescriptor namespace = memberResolver.resolveNamespace(fqName, IGNORE_KOTLIN_SOURCES);
116                if (namespace != null) {
117                    result.add(namespace);
118                }
119            }
120    
121            return result;
122        }
123    
124        @Override
125        @NotNull
126        protected Set<FunctionDescriptor> computeFunctionDescriptor(@NotNull Name name) {
127            NamedMembers members = membersProvider.get(name);
128            if (members == null) {
129                return Collections.emptySet();
130            }
131            SamConstructorDescriptor samConstructor = JavaFunctionResolver.resolveSamConstructor((NamespaceDescriptor) descriptor, members);
132            if (samConstructor == null) {
133                return Collections.emptySet();
134            }
135            return Collections.<FunctionDescriptor>singleton(samConstructor);
136        }
137    
138        @NotNull
139        @Override
140        protected Collection<ClassDescriptor> computeInnerClasses() {
141            return Collections.emptyList();
142        }
143    }