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.resolve.lazy;
018
019 import com.intellij.psi.PsiElement;
020 import kotlin.jvm.functions.Function0;
021 import kotlin.jvm.functions.Function1;
022 import org.jetbrains.annotations.NotNull;
023 import org.jetbrains.kotlin.descriptors.PackageViewDescriptor;
024 import org.jetbrains.kotlin.name.FqName;
025 import org.jetbrains.kotlin.psi.JetFile;
026 import org.jetbrains.kotlin.psi.JetImportDirective;
027 import org.jetbrains.kotlin.psi.JetImportsFactory;
028 import org.jetbrains.kotlin.resolve.ImportPath;
029 import org.jetbrains.kotlin.resolve.TemporaryBindingTrace;
030 import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
031 import org.jetbrains.kotlin.resolve.scopes.JetScope;
032 import org.jetbrains.kotlin.storage.MemoizedFunctionToNotNull;
033 import org.jetbrains.kotlin.storage.NotNullLazyValue;
034
035 import javax.inject.Inject;
036 import java.util.Collection;
037 import java.util.Collections;
038 import java.util.List;
039
040 public class ScopeProvider implements DeclarationScopeProvider, FileScopeProvider {
041
042 public static class AdditionalFileScopeProvider {
043 @NotNull
044 public List<JetScope> scopes(@NotNull JetFile file) {
045 return Collections.emptyList();
046 }
047 }
048
049 private final ResolveSession resolveSession;
050
051 private final NotNullLazyValue<Collection<JetImportDirective>> defaultImports;
052
053 private final MemoizedFunctionToNotNull<JetFile, LazyFileScope> fileScopes;
054
055 private AdditionalFileScopeProvider additionalFileScopeProvider;
056 private DeclarationScopeProvider declarationScopeProvider;
057
058 @Inject
059 public void setAdditionalFileScopesProvider(@NotNull AdditionalFileScopeProvider additionalFileScopeProvider) {
060 this.additionalFileScopeProvider = additionalFileScopeProvider;
061 }
062
063 @Inject
064 public void setDeclarationScopeProvider(@NotNull DeclarationScopeProviderImpl declarationScopeProvider) {
065 this.declarationScopeProvider = declarationScopeProvider;
066 }
067
068 public ScopeProvider(@NotNull final ResolveSession resolveSession) {
069 this.resolveSession = resolveSession;
070
071 this.defaultImports = resolveSession.getStorageManager().createLazyValue(new Function0<Collection<JetImportDirective>>() {
072 @Override
073 public Collection<JetImportDirective> invoke() {
074 PackageViewDescriptor rootPackage = resolveSession.getModuleDescriptor().getPackage(FqName.ROOT);
075 if (rootPackage == null) {
076 throw new IllegalStateException("Root package not found");
077 }
078
079 JetImportsFactory importsFactory = resolveSession.getJetImportsFactory();
080 List<ImportPath> defaultImports = resolveSession.getModuleDescriptor().getDefaultImports();
081
082 return importsFactory.createImportDirectives(defaultImports);
083 }
084 });
085
086
087 this.fileScopes = resolveSession.getStorageManager().createMemoizedFunction(new Function1<JetFile, LazyFileScope>() {
088 @Override
089 public LazyFileScope invoke(JetFile file) {
090 return createFileScope(file);
091 }
092 });
093 }
094
095 @Override
096 @NotNull
097 public LazyFileScope getFileScope(@NotNull JetFile file) {
098 return fileScopes.invoke(file);
099 }
100
101 private LazyFileScope createFileScope(@NotNull JetFile file) {
102 TemporaryBindingTrace tempTrace = TemporaryBindingTrace.create(resolveSession.getTrace(), "Transient trace for default imports lazy resolve");
103 return LazyFileScope.Factory.create(
104 resolveSession,
105 file,
106 defaultImports.invoke(),
107 additionalFileScopeProvider.scopes(file),
108 resolveSession.getTrace(),
109 tempTrace,
110 "LazyFileScope for file " + file.getName());
111 }
112
113 @NotNull
114 @Override
115 public JetScope getResolutionScopeForDeclaration(@NotNull PsiElement elementOfDeclaration) {
116 return declarationScopeProvider.getResolutionScopeForDeclaration(elementOfDeclaration);
117 }
118
119 @NotNull
120 @Override
121 public DataFlowInfo getOuterDataFlowInfoForDeclaration(@NotNull PsiElement elementOfDeclaration) {
122 return declarationScopeProvider.getOuterDataFlowInfoForDeclaration(elementOfDeclaration);
123 }
124 }