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.collections.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.DataFlowInfoFactory; 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, DataFlowInfoFactory.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