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 }