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.lazy.descriptors;
018
019 import com.intellij.util.Function;
020 import org.jetbrains.annotations.NotNull;
021 import org.jetbrains.annotations.Nullable;
022 import org.jetbrains.jet.lang.descriptors.*;
023 import org.jetbrains.jet.lang.psi.JetDeclaration;
024 import org.jetbrains.jet.lang.psi.JetFile;
025 import org.jetbrains.jet.lang.resolve.DescriptorUtils;
026 import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
027 import org.jetbrains.jet.lang.resolve.lazy.declarations.PackageMemberDeclarationProvider;
028 import org.jetbrains.jet.lang.resolve.lazy.storage.MemoizedFunctionToNullable;
029 import org.jetbrains.jet.lang.resolve.lazy.storage.StorageManager;
030 import org.jetbrains.jet.lang.resolve.name.FqName;
031 import org.jetbrains.jet.lang.resolve.name.Name;
032 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
033
034 import java.util.Collection;
035 import java.util.Set;
036
037 public class LazyPackageMemberScope extends AbstractLazyMemberScope<NamespaceDescriptor, PackageMemberDeclarationProvider> {
038
039 private final MemoizedFunctionToNullable<Name, NamespaceDescriptor> packageDescriptors;
040
041 public LazyPackageMemberScope(@NotNull ResolveSession resolveSession,
042 @NotNull PackageMemberDeclarationProvider declarationProvider,
043 @NotNull NamespaceDescriptor thisPackage) {
044 super(resolveSession, declarationProvider, thisPackage);
045
046 this.packageDescriptors = resolveSession.getStorageManager().createMemoizedFunctionWithNullableValues(
047 new Function<Name, NamespaceDescriptor>() {
048 @Override
049 public NamespaceDescriptor fun(Name name) {
050 return createPackageDescriptor(name);
051 }
052 }, StorageManager.ReferenceKind.STRONG);
053 }
054
055 @Override
056 public NamespaceDescriptor getNamespace(@NotNull Name name) {
057 return packageDescriptors.fun(name);
058 }
059
060 @Nullable
061 public NamespaceDescriptor createPackageDescriptor(@NotNull Name name) {
062 if (!declarationProvider.isPackageDeclared(name)) return null;
063
064 PackageMemberDeclarationProvider packageMemberDeclarationProvider = resolveSession.getDeclarationProviderFactory().getPackageMemberDeclarationProvider(
065 DescriptorUtils.getFQName(thisDescriptor).child(name).toSafe());
066 assert packageMemberDeclarationProvider != null : "Package is declared, but declaration provider is not found: " + name;
067
068 return new LazyPackageDescriptor(thisDescriptor, name, resolveSession, packageMemberDeclarationProvider);
069 }
070
071 @Override
072 public ClassifierDescriptor getClassifier(@NotNull Name name) {
073 // TODO: creating an FqName every time may be a performance problem
074 Name actualName = resolveSession.resolveClassifierAlias(DescriptorUtils.getFQName(thisDescriptor).toSafe(), name);
075 return super.getClassifier(actualName);
076 }
077
078 @NotNull
079 @Override
080 protected JetScope getScopeForMemberDeclarationResolution(JetDeclaration declaration) {
081 return resolveSession.getInjector().getScopeProvider().getFileScope((JetFile) declaration.getContainingFile());
082 }
083
084 @Override
085 protected ReceiverParameterDescriptor getImplicitReceiver() {
086 return ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
087 }
088
089 @Override
090 protected void getNonDeclaredFunctions(@NotNull Name name, @NotNull Set<FunctionDescriptor> result) {
091 // No extra functions
092 }
093
094 @Override
095 protected void getNonDeclaredProperties(@NotNull Name name, @NotNull Set<VariableDescriptor> result) {
096 // No extra properties
097 }
098
099 @Override
100 protected void addExtraDescriptors(@NotNull Collection<DeclarationDescriptor> result) {
101 for (FqName packageFqName : declarationProvider.getAllDeclaredPackages()) {
102 result.add(getNamespace(packageFqName.shortName()));
103 }
104 }
105
106 @Override
107 public String toString() {
108 // Do not add details here, they may compromise the laziness during debugging
109 return "lazy scope for package " + thisDescriptor.getName();
110 }
111 }