001 /*
002 * Copyright 2010-2014 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.jet.lang.resolve.java;
018
019 import com.google.common.base.Predicate;
020 import com.google.common.collect.ImmutableList;
021 import com.intellij.openapi.project.Project;
022 import com.intellij.psi.PsiFile;
023 import org.jetbrains.annotations.NotNull;
024 import org.jetbrains.jet.analyzer.AnalyzeExhaust;
025 import org.jetbrains.jet.analyzer.AnalyzerFacade;
026 import org.jetbrains.jet.context.ContextPackage;
027 import org.jetbrains.jet.context.GlobalContext;
028 import org.jetbrains.jet.context.GlobalContextImpl;
029 import org.jetbrains.jet.di.InjectorForLazyResolveWithJava;
030 import org.jetbrains.jet.di.InjectorForTopDownAnalyzerForJvm;
031 import org.jetbrains.jet.lang.descriptors.DependencyKind;
032 import org.jetbrains.jet.lang.descriptors.ModuleDescriptorImpl;
033 import org.jetbrains.jet.lang.psi.JetFile;
034 import org.jetbrains.jet.lang.resolve.BindingTrace;
035 import org.jetbrains.jet.lang.resolve.BindingTraceContext;
036 import org.jetbrains.jet.lang.resolve.ImportPath;
037 import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
038 import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
039 import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCache;
040 import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCacheProvider;
041 import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalPackageFragmentProvider;
042 import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
043 import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactory;
044 import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactoryService;
045 import org.jetbrains.jet.lang.resolve.name.Name;
046 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
047
048 import java.io.File;
049 import java.util.Collection;
050 import java.util.List;
051
052 public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
053
054 INSTANCE;
055
056 public static final List<ImportPath> DEFAULT_IMPORTS = ImmutableList.of(
057 new ImportPath("java.lang.*"),
058 new ImportPath("kotlin.*"),
059 new ImportPath("kotlin.jvm.*"),
060 new ImportPath("kotlin.io.*")
061 );
062
063 public static class JvmSetup extends BasicSetup {
064
065 private final JavaDescriptorResolver javaDescriptorResolver;
066
067 public JvmSetup(@NotNull ResolveSession session, @NotNull JavaDescriptorResolver javaDescriptorResolver) {
068 super(session);
069 this.javaDescriptorResolver = javaDescriptorResolver;
070 }
071
072 @NotNull
073 public JavaDescriptorResolver getJavaDescriptorResolver() {
074 return javaDescriptorResolver;
075 }
076 }
077
078 private AnalyzerFacadeForJVM() {
079 }
080
081 @NotNull
082 @Override
083 public JvmSetup createSetup(@NotNull Project fileProject, @NotNull Collection<JetFile> files) {
084 return createSetup(fileProject, files, new BindingTraceContext(), true);
085 }
086
087 @NotNull
088 public static ResolveSession createLazyResolveSession(
089 @NotNull Project project,
090 @NotNull Collection<JetFile> files,
091 @NotNull BindingTrace trace,
092 boolean addBuiltIns
093 ) {
094
095 return createSetup(project, files, trace, addBuiltIns).getLazyResolveSession();
096 }
097
098 private static JvmSetup createSetup(
099 Project project,
100 Collection<JetFile> files,
101 BindingTrace trace,
102 boolean addBuiltIns
103 ) {
104 GlobalContextImpl globalContext = ContextPackage.GlobalContext();
105
106 DeclarationProviderFactory declarationProviderFactory =
107 DeclarationProviderFactoryService.createDeclarationProviderFactory(project, globalContext.getStorageManager(), files);
108
109 InjectorForLazyResolveWithJava resolveWithJava = new InjectorForLazyResolveWithJava(
110 project,
111 globalContext,
112 declarationProviderFactory,
113 trace);
114
115 resolveWithJava.getModule().addFragmentProvider(
116 DependencyKind.BINARIES, resolveWithJava.getJavaDescriptorResolver().getPackageFragmentProvider());
117
118 if (addBuiltIns) {
119 resolveWithJava.getModule().addFragmentProvider(
120 DependencyKind.BUILT_INS,
121 KotlinBuiltIns.getInstance().getBuiltInsModule().getPackageFragmentProvider());
122 }
123 return new JvmSetup(resolveWithJava.getResolveSession(), resolveWithJava.getJavaDescriptorResolver());
124 }
125
126 @NotNull
127 public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
128 Project project,
129 Collection<JetFile> files,
130 BindingTrace trace,
131 Predicate<PsiFile> filesToAnalyzeCompletely,
132 ModuleDescriptorImpl module,
133 List<String> moduleIds,
134 File incrementalCacheDir
135 ) {
136 GlobalContext globalContext = ContextPackage.GlobalContext();
137 TopDownAnalysisParameters topDownAnalysisParameters = TopDownAnalysisParameters.create(
138 globalContext.getStorageManager(),
139 globalContext.getExceptionTracker(),
140 filesToAnalyzeCompletely,
141 false,
142 false
143 );
144
145 InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm(project, topDownAnalysisParameters, trace, module);
146 try {
147 module.addFragmentProvider(DependencyKind.BINARIES, injector.getJavaDescriptorResolver().getPackageFragmentProvider());
148
149 IncrementalCacheProvider incrementalCacheProvider = IncrementalCacheProvider.object$.getInstance();
150 if (incrementalCacheDir != null && moduleIds != null && incrementalCacheProvider != null) {
151 IncrementalCache incrementalCache = incrementalCacheProvider.getIncrementalCache(incrementalCacheDir);
152 for (String moduleId : moduleIds) {
153 module.addFragmentProvider(
154 DependencyKind.SOURCES,
155 new IncrementalPackageFragmentProvider(
156 files, module, globalContext.getStorageManager(), injector.getDeserializationGlobalContextForJava(),
157 incrementalCache, moduleId, injector.getJavaDescriptorResolver()
158 )
159 );
160 }
161 }
162
163 injector.getTopDownAnalyzer().analyzeFiles(topDownAnalysisParameters, files);
164 return AnalyzeExhaust.success(trace.getBindingContext(), module);
165 }
166 finally {
167 injector.destroy();
168 }
169 }
170
171 @NotNull
172 public static ModuleDescriptorImpl createJavaModule(@NotNull String name) {
173 return new ModuleDescriptorImpl(Name.special(name), DEFAULT_IMPORTS, JavaToKotlinClassMap.getInstance());
174 }
175 }