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.Function0; 021 import kotlin.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 }