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