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.google.common.base.Predicate; 020 import com.intellij.openapi.project.Project; 021 import com.intellij.psi.PsiFile; 022 import com.intellij.psi.search.GlobalSearchScope; 023 import org.jetbrains.annotations.NotNull; 024 import org.jetbrains.annotations.Nullable; 025 import org.jetbrains.kotlin.analyzer.AnalysisResult; 026 import org.jetbrains.kotlin.builtins.KotlinBuiltIns; 027 import org.jetbrains.kotlin.context.GlobalContext; 028 import org.jetbrains.kotlin.descriptors.ClassDescriptor; 029 import org.jetbrains.kotlin.descriptors.PackageFragmentProvider; 030 import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl; 031 import org.jetbrains.kotlin.di.InjectorForTopDownAnalyzerForJvm; 032 import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider; 033 import org.jetbrains.kotlin.load.kotlin.incremental.cache.IncrementalCache; 034 import org.jetbrains.kotlin.load.kotlin.incremental.cache.IncrementalCacheProvider; 035 import org.jetbrains.kotlin.name.FqName; 036 import org.jetbrains.kotlin.name.Name; 037 import org.jetbrains.kotlin.platform.JavaToKotlinClassMap; 038 import org.jetbrains.kotlin.psi.JetFile; 039 import org.jetbrains.kotlin.resolve.BindingTrace; 040 import org.jetbrains.kotlin.resolve.DescriptorUtils; 041 import org.jetbrains.kotlin.resolve.ImportPath; 042 import org.jetbrains.kotlin.resolve.TopDownAnalysisParameters; 043 import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory; 044 045 import java.util.ArrayList; 046 import java.util.Collection; 047 import java.util.List; 048 049 public enum TopDownAnalyzerFacadeForJVM { 050 051 INSTANCE; 052 053 public static final List<ImportPath> DEFAULT_IMPORTS = buildDefaultImports(); 054 055 private static List<ImportPath> buildDefaultImports() { 056 List<ImportPath> list = new ArrayList<ImportPath>(); 057 list.add(new ImportPath("java.lang.*")); 058 list.add(new ImportPath("kotlin.*")); 059 list.add(new ImportPath("kotlin.jvm.*")); 060 list.add(new ImportPath("kotlin.io.*")); 061 // all classes from package "kotlin" mapped to java classes are imported explicitly so that they take priority over classes from java.lang 062 for (ClassDescriptor descriptor : JavaToKotlinClassMap.INSTANCE.allKotlinClasses()) { 063 FqName fqName = DescriptorUtils.getFqNameSafe(descriptor); 064 if (fqName.parent().equals(new FqName("kotlin"))) { 065 list.add(new ImportPath(fqName, false)); 066 } 067 } 068 return list; 069 } 070 071 private TopDownAnalyzerFacadeForJVM() { 072 } 073 074 @NotNull 075 public static AnalysisResult analyzeFilesWithJavaIntegrationNoIncremental( 076 @NotNull Project project, 077 @NotNull Collection<JetFile> files, 078 @NotNull BindingTrace trace, 079 @NotNull TopDownAnalysisParameters topDownAnalysisParameters, 080 @NotNull ModuleDescriptorImpl module 081 ) { 082 return analyzeFilesWithJavaIntegration(project, files, trace, topDownAnalysisParameters, module, null, null); 083 } 084 085 @NotNull 086 public static AnalysisResult analyzeFilesWithJavaIntegrationWithCustomContext( 087 @NotNull Project project, 088 @NotNull GlobalContext globalContext, 089 @NotNull Collection<JetFile> files, 090 @NotNull BindingTrace trace, 091 @NotNull Predicate<PsiFile> filesToAnalyzeCompletely, 092 @NotNull ModuleDescriptorImpl module, 093 @Nullable List<String> moduleIds, 094 @Nullable IncrementalCacheProvider incrementalCacheProvider 095 ) { 096 TopDownAnalysisParameters topDownAnalysisParameters = TopDownAnalysisParameters.create( 097 globalContext.getStorageManager(), 098 globalContext.getExceptionTracker(), 099 filesToAnalyzeCompletely, 100 false, 101 false 102 ); 103 104 return analyzeFilesWithJavaIntegration( 105 project, files, trace, topDownAnalysisParameters, module, 106 moduleIds, incrementalCacheProvider); 107 } 108 109 @NotNull 110 private static AnalysisResult analyzeFilesWithJavaIntegration( 111 Project project, 112 Collection<JetFile> files, 113 BindingTrace trace, 114 TopDownAnalysisParameters topDownAnalysisParameters, 115 ModuleDescriptorImpl module, 116 @Nullable List<String> moduleIds, 117 @Nullable IncrementalCacheProvider incrementalCacheProvider 118 ) { 119 List<JetFile> allFiles = JvmAnalyzerFacade.getAllFilesToAnalyze(project, null, files); 120 121 FileBasedDeclarationProviderFactory providerFactory = 122 new FileBasedDeclarationProviderFactory(topDownAnalysisParameters.getStorageManager(), allFiles); 123 124 InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm( 125 project, 126 topDownAnalysisParameters, 127 trace, 128 module, 129 providerFactory, 130 GlobalSearchScope.allScope(project) 131 ); 132 133 try { 134 List<PackageFragmentProvider> additionalProviders = new ArrayList<PackageFragmentProvider>(); 135 136 if (moduleIds != null && incrementalCacheProvider != null) { 137 for (String moduleId : moduleIds) { 138 IncrementalCache incrementalCache = incrementalCacheProvider.getIncrementalCache(moduleId); 139 140 additionalProviders.add( 141 new IncrementalPackageFragmentProvider( 142 files, module, topDownAnalysisParameters.getStorageManager(), 143 injector.getDeserializationComponentsForJava().getComponents(), 144 incrementalCache, moduleId 145 ) 146 ); 147 } 148 } 149 additionalProviders.add(injector.getJavaDescriptorResolver().getPackageFragmentProvider()); 150 151 injector.getLazyTopDownAnalyzerForTopLevel().analyzeFiles(topDownAnalysisParameters, allFiles, additionalProviders); 152 return AnalysisResult.success(trace.getBindingContext(), module); 153 } 154 finally { 155 injector.destroy(); 156 } 157 } 158 159 @NotNull 160 public static ModuleDescriptorImpl createJavaModule(@NotNull String name) { 161 return new ModuleDescriptorImpl(Name.special(name), 162 DEFAULT_IMPORTS, 163 JavaToKotlinClassMap.INSTANCE); 164 } 165 166 @NotNull 167 public static ModuleDescriptorImpl createSealedJavaModule() { 168 ModuleDescriptorImpl module = createJavaModule("<shared-module>"); 169 module.addDependencyOnModule(module); 170 module.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule()); 171 module.seal(); 172 return module; 173 } 174 }