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.builtins.KotlinBuiltIns; 025 import org.jetbrains.kotlin.context.ModuleContext; 026 import org.jetbrains.kotlin.context.MutableModuleContext; 027 import org.jetbrains.kotlin.descriptors.*; 028 import org.jetbrains.kotlin.frontend.java.di.ContainerForTopDownAnalyzerForJvm; 029 import org.jetbrains.kotlin.frontend.java.di.DiPackage; 030 import org.jetbrains.kotlin.incremental.components.LookupTracker; 031 import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider; 032 import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider; 033 import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache; 034 import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents; 035 import org.jetbrains.kotlin.modules.Module; 036 import org.jetbrains.kotlin.modules.ModulesPackage; 037 import org.jetbrains.kotlin.modules.TargetId; 038 import org.jetbrains.kotlin.name.Name; 039 import org.jetbrains.kotlin.platform.JavaToKotlinClassMap; 040 import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap; 041 import org.jetbrains.kotlin.psi.JetFile; 042 import org.jetbrains.kotlin.resolve.*; 043 import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisCompletedHandlerExtension; 044 import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory; 045 import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter; 046 import org.jetbrains.kotlin.resolve.scopes.JetScope; 047 048 import java.util.ArrayList; 049 import java.util.Collection; 050 import java.util.List; 051 052 import static org.jetbrains.kotlin.context.ContextPackage.ContextForNewModule; 053 054 public enum TopDownAnalyzerFacadeForJVM { 055 056 INSTANCE; 057 058 public static final List<ImportPath> DEFAULT_IMPORTS = buildDefaultImports(); 059 060 private static void addAllClassifiersToImportPathList(List<ImportPath> list, JetScope scope) { 061 for (DeclarationDescriptor descriptor : scope.getDescriptors(DescriptorKindFilter.CLASSIFIERS, JetScope.ALL_NAME_FILTER)) { 062 list.add(new ImportPath(DescriptorUtils.getFqNameSafe(descriptor), false)); 063 } 064 } 065 066 private static List<ImportPath> buildDefaultImports() { 067 List<ImportPath> list = new ArrayList<ImportPath>(); 068 list.add(new ImportPath("java.lang.*")); 069 list.add(new ImportPath("kotlin.*")); 070 list.add(new ImportPath("kotlin.annotation.*")); 071 list.add(new ImportPath("kotlin.jvm.*")); 072 list.add(new ImportPath("kotlin.io.*")); 073 074 addAllClassifiersToImportPathList(list, KotlinBuiltIns.getInstance().getBuiltInsPackageScope()); 075 addAllClassifiersToImportPathList(list, KotlinBuiltIns.getInstance().getAnnotationPackageScope()); 076 077 return list; 078 } 079 080 public static ModuleParameters JVM_MODULE_PARAMETERS = new ModuleParameters() { 081 @NotNull 082 @Override 083 public List<ImportPath> getDefaultImports() { 084 return DEFAULT_IMPORTS; 085 } 086 087 @NotNull 088 @Override 089 public PlatformToKotlinClassMap getPlatformToKotlinClassMap() { 090 return JavaToKotlinClassMap.INSTANCE; 091 } 092 }; 093 094 @NotNull 095 public static AnalysisResult analyzeFilesWithJavaIntegrationNoIncremental( 096 @NotNull ModuleContext moduleContext, 097 @NotNull Collection<JetFile> files, 098 @NotNull BindingTrace trace, 099 @NotNull TopDownAnalysisMode topDownAnalysisMode, 100 PackagePartProvider packagePartProvider 101 ) { 102 return analyzeFilesWithJavaIntegration(moduleContext, files, trace, topDownAnalysisMode, null, null, packagePartProvider); 103 } 104 105 @NotNull 106 public static AnalysisResult analyzeFilesWithJavaIntegrationWithCustomContext( 107 @NotNull ModuleContext moduleContext, 108 @NotNull Collection<JetFile> files, 109 @NotNull BindingTrace trace, 110 @Nullable List<Module> modules, 111 @Nullable IncrementalCompilationComponents incrementalCompilationComponents, 112 @NotNull PackagePartProvider packagePartProvider 113 ) { 114 return analyzeFilesWithJavaIntegration( 115 moduleContext, files, trace, TopDownAnalysisMode.TopLevelDeclarations, modules, incrementalCompilationComponents, 116 packagePartProvider); 117 } 118 119 @NotNull 120 private static AnalysisResult analyzeFilesWithJavaIntegration( 121 @NotNull ModuleContext moduleContext, 122 @NotNull Collection<JetFile> files, 123 @NotNull BindingTrace trace, 124 @NotNull TopDownAnalysisMode topDownAnalysisMode, 125 @Nullable List<Module> modules, 126 @Nullable IncrementalCompilationComponents incrementalCompilationComponents, 127 @NotNull PackagePartProvider packagePartProvider 128 ) { 129 Project project = moduleContext.getProject(); 130 List<JetFile> allFiles = JvmAnalyzerFacade.getAllFilesToAnalyze(project, null, files); 131 132 FileBasedDeclarationProviderFactory providerFactory = 133 new FileBasedDeclarationProviderFactory(moduleContext.getStorageManager(), allFiles); 134 135 LookupTracker lookupTracker = 136 incrementalCompilationComponents != null ? incrementalCompilationComponents.getLookupTracker() : LookupTracker.DO_NOTHING; 137 138 List<TargetId> targetIds = null; 139 if (modules != null) { 140 targetIds = new ArrayList<TargetId>(modules.size()); 141 142 for (Module module : modules) { 143 targetIds.add(ModulesPackage.TargetId(module)); 144 } 145 } 146 147 packagePartProvider = IncrementalPackagePartProvider.create(packagePartProvider, files, targetIds, incrementalCompilationComponents, moduleContext.getStorageManager()); 148 149 ContainerForTopDownAnalyzerForJvm container = DiPackage.createContainerForTopDownAnalyzerForJvm( 150 moduleContext, 151 trace, 152 providerFactory, 153 GlobalSearchScope.allScope(project), 154 lookupTracker, 155 packagePartProvider 156 ); 157 158 List<PackageFragmentProvider> additionalProviders = new ArrayList<PackageFragmentProvider>(); 159 160 if (targetIds != null && incrementalCompilationComponents != null) { 161 for (TargetId targetId : targetIds) { 162 IncrementalCache incrementalCache = incrementalCompilationComponents.getIncrementalCache(targetId); 163 164 additionalProviders.add( 165 new IncrementalPackageFragmentProvider( 166 files, moduleContext.getModule(), moduleContext.getStorageManager(), 167 container.getDeserializationComponentsForJava().getComponents(), 168 incrementalCache, targetId 169 ) 170 ); 171 } 172 } 173 additionalProviders.add(container.getJavaDescriptorResolver().getPackageFragmentProvider()); 174 175 container.getLazyTopDownAnalyzerForTopLevel().analyzeFiles(topDownAnalysisMode, allFiles, additionalProviders); 176 177 BindingContext bindingContext = trace.getBindingContext(); 178 ModuleDescriptor module = moduleContext.getModule(); 179 180 Collection<AnalysisCompletedHandlerExtension> analysisCompletedHandlerExtensions = 181 AnalysisCompletedHandlerExtension.Companion.getInstances(moduleContext.getProject()); 182 183 for (AnalysisCompletedHandlerExtension extension : analysisCompletedHandlerExtensions) { 184 AnalysisResult result = extension.analysisCompleted(project, module, bindingContext, files); 185 if (result != null) return result; 186 } 187 188 return AnalysisResult.success(bindingContext, module); 189 } 190 191 @NotNull 192 public static MutableModuleContext createContextWithSealedModule(@NotNull Project project, @NotNull String moduleName) { 193 MutableModuleContext context = ContextForNewModule( 194 project, Name.special("<" + moduleName + ">"), JVM_MODULE_PARAMETERS 195 ); 196 context.setDependencies(context.getModule(), KotlinBuiltIns.getInstance().getBuiltInsModule()); 197 return context; 198 } 199 }