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.jvm; 018 019 import com.intellij.openapi.project.Project; 020 import com.intellij.psi.search.GlobalSearchScope; 021 import org.jetbrains.annotations.NotNull; 022 import org.jetbrains.annotations.Nullable; 023 import org.jetbrains.kotlin.analyzer.AnalysisResult; 024 import org.jetbrains.kotlin.context.ContextKt; 025 import org.jetbrains.kotlin.context.ModuleContext; 026 import org.jetbrains.kotlin.context.MutableModuleContext; 027 import org.jetbrains.kotlin.descriptors.ModuleDescriptor; 028 import org.jetbrains.kotlin.descriptors.PackageFragmentProvider; 029 import org.jetbrains.kotlin.descriptors.PackagePartProvider; 030 import org.jetbrains.kotlin.frontend.java.di.ContainerForTopDownAnalyzerForJvm; 031 import org.jetbrains.kotlin.frontend.java.di.InjectionKt; 032 import org.jetbrains.kotlin.incremental.components.LookupTracker; 033 import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider; 034 import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider; 035 import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache; 036 import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents; 037 import org.jetbrains.kotlin.modules.Module; 038 import org.jetbrains.kotlin.modules.TargetId; 039 import org.jetbrains.kotlin.modules.TargetIdKt; 040 import org.jetbrains.kotlin.name.Name; 041 import org.jetbrains.kotlin.psi.KtFile; 042 import org.jetbrains.kotlin.resolve.BindingContext; 043 import org.jetbrains.kotlin.resolve.BindingTrace; 044 import org.jetbrains.kotlin.resolve.TopDownAnalysisMode; 045 import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisCompletedHandlerExtension; 046 import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension; 047 import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform; 048 import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory; 049 050 import java.util.ArrayList; 051 import java.util.Collection; 052 import java.util.List; 053 054 public enum TopDownAnalyzerFacadeForJVM { 055 056 INSTANCE; 057 058 @NotNull 059 public static AnalysisResult analyzeFilesWithJavaIntegrationNoIncremental( 060 @NotNull ModuleContext moduleContext, 061 @NotNull Collection<KtFile> files, 062 @NotNull BindingTrace trace, 063 @NotNull TopDownAnalysisMode topDownAnalysisMode, 064 PackagePartProvider packagePartProvider 065 ) { 066 return analyzeFilesWithJavaIntegration(moduleContext, files, trace, topDownAnalysisMode, null, null, packagePartProvider); 067 } 068 069 @NotNull 070 public static AnalysisResult analyzeFilesWithJavaIntegrationWithCustomContext( 071 @NotNull ModuleContext moduleContext, 072 @NotNull Collection<KtFile> files, 073 @NotNull BindingTrace trace, 074 @Nullable List<Module> modules, 075 @Nullable IncrementalCompilationComponents incrementalCompilationComponents, 076 @NotNull PackagePartProvider packagePartProvider 077 ) { 078 return analyzeFilesWithJavaIntegration( 079 moduleContext, files, trace, TopDownAnalysisMode.TopLevelDeclarations, modules, incrementalCompilationComponents, 080 packagePartProvider); 081 } 082 083 @NotNull 084 private static AnalysisResult analyzeFilesWithJavaIntegration( 085 @NotNull ModuleContext moduleContext, 086 @NotNull Collection<KtFile> files, 087 @NotNull BindingTrace trace, 088 @NotNull TopDownAnalysisMode topDownAnalysisMode, 089 @Nullable List<Module> modules, 090 @Nullable IncrementalCompilationComponents incrementalCompilationComponents, 091 @NotNull PackagePartProvider packagePartProvider 092 ) { 093 Project project = moduleContext.getProject(); 094 List<KtFile> allFiles = JvmAnalyzerFacade.getAllFilesToAnalyze(project, null, files); 095 096 FileBasedDeclarationProviderFactory providerFactory = 097 new FileBasedDeclarationProviderFactory(moduleContext.getStorageManager(), allFiles); 098 099 LookupTracker lookupTracker = 100 incrementalCompilationComponents != null ? incrementalCompilationComponents.getLookupTracker() : LookupTracker.Companion.getDO_NOTHING(); 101 102 List<TargetId> targetIds = null; 103 if (modules != null) { 104 targetIds = new ArrayList<TargetId>(modules.size()); 105 106 for (Module module : modules) { 107 targetIds.add(TargetIdKt.TargetId(module)); 108 } 109 } 110 111 packagePartProvider = IncrementalPackagePartProvider.create(packagePartProvider, files, targetIds, incrementalCompilationComponents, moduleContext.getStorageManager()); 112 113 ContainerForTopDownAnalyzerForJvm container = InjectionKt.createContainerForTopDownAnalyzerForJvm( 114 moduleContext, 115 trace, 116 providerFactory, 117 GlobalSearchScope.allScope(project), 118 lookupTracker, 119 packagePartProvider 120 ); 121 122 List<PackageFragmentProvider> additionalProviders = new ArrayList<PackageFragmentProvider>(); 123 124 if (targetIds != null && incrementalCompilationComponents != null) { 125 for (TargetId targetId : targetIds) { 126 IncrementalCache incrementalCache = incrementalCompilationComponents.getIncrementalCache(targetId); 127 128 additionalProviders.add( 129 new IncrementalPackageFragmentProvider( 130 files, moduleContext.getModule(), moduleContext.getStorageManager(), 131 container.getDeserializationComponentsForJava().getComponents(), 132 incrementalCache, targetId 133 ) 134 ); 135 } 136 } 137 additionalProviders.add(container.getJavaDescriptorResolver().getPackageFragmentProvider()); 138 139 for (PackageFragmentProviderExtension extension : PackageFragmentProviderExtension.Companion.getInstances(project)) { 140 PackageFragmentProvider provider = extension.getPackageFragmentProvider( 141 project, moduleContext.getModule(), moduleContext.getStorageManager(), trace, null); 142 if (provider != null) additionalProviders.add(provider); 143 } 144 145 container.getLazyTopDownAnalyzerForTopLevel().analyzeFiles(topDownAnalysisMode, allFiles, additionalProviders); 146 147 BindingContext bindingContext = trace.getBindingContext(); 148 ModuleDescriptor module = moduleContext.getModule(); 149 150 Collection<AnalysisCompletedHandlerExtension> analysisCompletedHandlerExtensions = 151 AnalysisCompletedHandlerExtension.Companion.getInstances(moduleContext.getProject()); 152 153 for (AnalysisCompletedHandlerExtension extension : analysisCompletedHandlerExtensions) { 154 AnalysisResult result = extension.analysisCompleted(project, module, bindingContext, files); 155 if (result != null) return result; 156 } 157 158 return AnalysisResult.success(bindingContext, module); 159 } 160 161 @NotNull 162 public static MutableModuleContext createContextWithSealedModule(@NotNull Project project, @NotNull String moduleName) { 163 MutableModuleContext context = ContextKt.ContextForNewModule( 164 project, Name.special("<" + moduleName + ">"), JvmPlatform.INSTANCE 165 ); 166 context.setDependencies(context.getModule(), JvmPlatform.INSTANCE.getBuiltIns().getBuiltInsModule()); 167 return context; 168 } 169 }