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; 018 019 import com.intellij.psi.PsiElement; 020 import kotlin.KotlinPackage; 021 import org.jetbrains.annotations.NotNull; 022 import org.jetbrains.kotlin.descriptors.PackageFragmentProvider; 023 import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider; 024 import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl; 025 import org.jetbrains.kotlin.psi.JetFile; 026 import org.jetbrains.kotlin.psi.JetScript; 027 import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; 028 import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer; 029 import org.jetbrains.kotlin.resolve.lazy.LazyFileScope; 030 031 import javax.inject.Inject; 032 import java.util.Arrays; 033 import java.util.Collection; 034 import java.util.List; 035 036 public class LazyTopDownAnalyzerForTopLevel { 037 038 private KotlinCodeAnalyzer resolveSession; 039 private LazyTopDownAnalyzer lazyTopDownAnalyzer; 040 041 @Inject 042 public void setKotlinCodeAnalyzer(@NotNull KotlinCodeAnalyzer kotlinCodeAnalyzer) { 043 this.resolveSession = kotlinCodeAnalyzer; 044 } 045 046 @Inject 047 public void setLazyTopDownAnalyzer(@NotNull LazyTopDownAnalyzer lazyTopDownAnalyzer) { 048 this.lazyTopDownAnalyzer = lazyTopDownAnalyzer; 049 } 050 051 @NotNull 052 public TopDownAnalysisContext analyzeFiles( 053 @NotNull TopDownAnalysisParameters topDownAnalysisParameters, 054 @NotNull Collection<JetFile> files, 055 @NotNull List<? extends PackageFragmentProvider> additionalProviders 056 ) { 057 assert topDownAnalysisParameters.isLazy() : "Lazy analyzer is run in non-lazy mode"; 058 059 PackageFragmentProvider provider; 060 if (additionalProviders.isEmpty()) { 061 provider = resolveSession.getPackageFragmentProvider(); 062 } 063 else { 064 provider = new CompositePackageFragmentProvider(KotlinPackage.plus( 065 Arrays.asList(resolveSession.getPackageFragmentProvider()), 066 additionalProviders)); 067 } 068 069 ((ModuleDescriptorImpl) resolveSession.getModuleDescriptor()).initialize(provider); 070 071 return analyzeDeclarations(topDownAnalysisParameters, files); 072 } 073 074 @NotNull 075 public TopDownAnalysisContext analyzeDeclarations( 076 @NotNull TopDownAnalysisParameters topDownAnalysisParameters, 077 @NotNull Collection<? extends PsiElement> elements 078 ) { 079 TopDownAnalysisContext c = lazyTopDownAnalyzer.analyzeDeclarations(topDownAnalysisParameters, elements, DataFlowInfo.EMPTY); 080 081 resolveImportsInAllFiles(c, resolveSession); 082 083 return c; 084 } 085 086 private static void resolveImportsInAllFiles(TopDownAnalysisContext c, KotlinCodeAnalyzer resolveSession) { 087 for (JetFile file : c.getFiles()) { 088 resolveAndCheckImports(file, resolveSession); 089 } 090 091 for (JetScript script : c.getScripts().keySet()) { 092 resolveAndCheckImports(script.getContainingJetFile(), resolveSession); 093 } 094 } 095 096 private static void resolveAndCheckImports(@NotNull JetFile file, @NotNull KotlinCodeAnalyzer resolveSession) { 097 LazyFileScope fileScope = resolveSession.getScopeProvider().getFileScope(file); 098 fileScope.forceResolveAllImports(); 099 } 100 } 101 102