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.CollectionsKt;
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.KtFile;
026 import org.jetbrains.kotlin.psi.KtScript;
027 import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
028 import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer;
029 import org.jetbrains.kotlin.resolve.lazy.ImportResolver;
030
031 import java.util.Arrays;
032 import java.util.Collection;
033 import java.util.List;
034
035 public class LazyTopDownAnalyzerForTopLevel {
036
037 @NotNull private final KotlinCodeAnalyzer codeAnalyzer;
038 @NotNull private final LazyTopDownAnalyzer lazyTopDownAnalyzer;
039
040 public LazyTopDownAnalyzerForTopLevel(
041 @NotNull LazyTopDownAnalyzer lazyTopDownAnalyzer,
042 @NotNull KotlinCodeAnalyzer codeAnalyzer
043 ) {
044 this.lazyTopDownAnalyzer = lazyTopDownAnalyzer;
045 this.codeAnalyzer = codeAnalyzer;
046 }
047
048 @NotNull
049 public TopDownAnalysisContext analyzeFiles(
050 @NotNull TopDownAnalysisMode topDownAnalysisMode,
051 @NotNull Collection<KtFile> files,
052 @NotNull List<? extends PackageFragmentProvider> additionalProviders
053 ) {
054 PackageFragmentProvider provider;
055 if (additionalProviders.isEmpty()) {
056 provider = codeAnalyzer.getPackageFragmentProvider();
057 }
058 else {
059 provider = new CompositePackageFragmentProvider(CollectionsKt.plus(
060 Arrays.asList(codeAnalyzer.getPackageFragmentProvider()),
061 additionalProviders));
062 }
063
064 ((ModuleDescriptorImpl) codeAnalyzer.getModuleDescriptor()).initialize(provider);
065
066 return analyzeDeclarations(topDownAnalysisMode, files);
067 }
068
069 @NotNull
070 public TopDownAnalysisContext analyzeDeclarations(
071 @NotNull TopDownAnalysisMode topDownAnalysisMode,
072 @NotNull Collection<? extends PsiElement> elements
073 ) {
074 TopDownAnalysisContext c = lazyTopDownAnalyzer.analyzeDeclarations(topDownAnalysisMode, elements, DataFlowInfo.EMPTY);
075
076 resolveImportsInAllFiles(c, codeAnalyzer);
077
078 return c;
079 }
080
081 private static void resolveImportsInAllFiles(TopDownAnalysisContext c, KotlinCodeAnalyzer resolveSession) {
082 for (KtFile file : c.getFiles()) {
083 resolveAndCheckImports(file, resolveSession);
084 }
085
086 for (KtScript script : c.getScripts().keySet()) {
087 resolveAndCheckImports(script.getContainingKtFile(), resolveSession);
088 }
089 }
090
091 private static void resolveAndCheckImports(@NotNull KtFile file, @NotNull KotlinCodeAnalyzer resolveSession) {
092 ImportResolver importResolver = resolveSession.getFileScopeProvider().getImportResolver(file);
093 importResolver.forceResolveAllImports();
094 }
095 }
096
097