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 017package org.jetbrains.jet.lang.resolve.lazy.descriptors; 018 019import com.intellij.util.Function; 020import org.jetbrains.annotations.NotNull; 021import org.jetbrains.annotations.Nullable; 022import org.jetbrains.jet.lang.descriptors.*; 023import org.jetbrains.jet.lang.psi.JetDeclaration; 024import org.jetbrains.jet.lang.psi.JetFile; 025import org.jetbrains.jet.lang.resolve.DescriptorUtils; 026import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; 027import org.jetbrains.jet.lang.resolve.lazy.declarations.PackageMemberDeclarationProvider; 028import org.jetbrains.jet.lang.resolve.lazy.storage.MemoizedFunctionToNullable; 029import org.jetbrains.jet.lang.resolve.lazy.storage.StorageManager; 030import org.jetbrains.jet.lang.resolve.name.FqName; 031import org.jetbrains.jet.lang.resolve.name.Name; 032import org.jetbrains.jet.lang.resolve.scopes.JetScope; 033 034import java.util.Collection; 035import java.util.Set; 036 037public 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}