001 /*
002 * Copyright 2010-2013 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.base.Predicates;
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.analyzer.AnalyzerFacadeForEverything;
027 import org.jetbrains.jet.di.InjectorForJavaDescriptorResolver;
028 import org.jetbrains.jet.di.InjectorForTopDownAnalyzerForJvm;
029 import org.jetbrains.jet.lang.ModuleConfiguration;
030 import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
031 import org.jetbrains.jet.lang.descriptors.ModuleDescriptorImpl;
032 import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
033 import org.jetbrains.jet.lang.psi.JetFile;
034 import org.jetbrains.jet.lang.resolve.*;
035 import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
036 import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
037 import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory;
038 import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedStorageManager;
039 import org.jetbrains.jet.lang.resolve.name.FqName;
040 import org.jetbrains.jet.lang.resolve.name.Name;
041 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
042 import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
043 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
044
045 import java.util.Collection;
046 import java.util.Collections;
047 import java.util.List;
048
049 public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
050
051 INSTANCE;
052
053 private AnalyzerFacadeForJVM() {
054 }
055
056 @Override
057 @NotNull
058 public AnalyzeExhaust analyzeFiles(@NotNull Project project,
059 @NotNull Collection<JetFile> files,
060 @NotNull List<AnalyzerScriptParameter> scriptParameters,
061 @NotNull Predicate<PsiFile> filesToAnalyzeCompletely) {
062 return analyzeFilesWithJavaIntegration(project, files, scriptParameters, filesToAnalyzeCompletely, true);
063 }
064
065 @NotNull
066 @Override
067 public AnalyzeExhaust analyzeBodiesInFiles(@NotNull Project project,
068 @NotNull List<AnalyzerScriptParameter> scriptParameters,
069 @NotNull Predicate<PsiFile> filesForBodiesResolve,
070 @NotNull BindingTrace headersTraceContext,
071 @NotNull BodiesResolveContext bodiesResolveContext,
072 @NotNull ModuleDescriptor module
073 ) {
074 return AnalyzerFacadeForEverything.analyzeBodiesInFilesWithJavaIntegration(
075 project, scriptParameters, filesForBodiesResolve,
076 headersTraceContext, bodiesResolveContext, module);
077 }
078
079 @NotNull
080 @Override
081 public ResolveSession getLazyResolveSession(@NotNull Project fileProject, @NotNull Collection<JetFile> files) {
082 BindingTraceContext javaResolverTrace = new BindingTraceContext();
083 InjectorForJavaDescriptorResolver injector = new InjectorForJavaDescriptorResolver(fileProject, javaResolverTrace);
084
085 final PsiClassFinder psiClassFinder = injector.getPsiClassFinder();
086
087 // TODO: Replace with stub declaration provider
088 LockBasedStorageManager storageManager = new LockBasedStorageManager();
089 FileBasedDeclarationProviderFactory declarationProviderFactory = new FileBasedDeclarationProviderFactory(storageManager, files, new Predicate<FqName>() {
090 @Override
091 public boolean apply(FqName fqName) {
092 return psiClassFinder.findPsiPackage(fqName) != null || new FqName("jet").equals(fqName);
093 }
094 });
095
096 final JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver();
097
098 ModuleConfiguration moduleConfiguration = new ModuleConfiguration() {
099
100 @Override
101 public void extendNamespaceScope(
102 @NotNull BindingTrace trace,
103 @NotNull NamespaceDescriptor namespaceDescriptor,
104 @NotNull WritableScope namespaceMemberScope
105 ) {
106 FqName fqName = DescriptorUtils.getFQName(namespaceDescriptor).toSafe();
107 if (new FqName("jet").equals(fqName)) {
108 namespaceMemberScope.importScope(KotlinBuiltIns.getInstance().getBuiltInsScope());
109 }
110 if (psiClassFinder.findPsiPackage(fqName) != null) {
111 JetScope javaPackageScope = javaDescriptorResolver.getJavaPackageScope(namespaceDescriptor);
112 assert javaPackageScope != null;
113 namespaceMemberScope.importScope(javaPackageScope);
114 }
115 }
116 };
117
118 ModuleDescriptorImpl lazyModule = createJavaModule("<lazy module>");
119 lazyModule.setModuleConfiguration(moduleConfiguration);
120
121 return new ResolveSession(fileProject, storageManager, lazyModule, declarationProviderFactory, javaResolverTrace);
122 }
123
124 public static AnalyzeExhaust analyzeOneFileWithJavaIntegrationAndCheckForErrors(
125 JetFile file, List<AnalyzerScriptParameter> scriptParameters) {
126 AnalyzingUtils.checkForSyntacticErrors(file);
127
128 AnalyzeExhaust analyzeExhaust = analyzeOneFileWithJavaIntegration(file, scriptParameters);
129
130 AnalyzingUtils.throwExceptionOnErrors(analyzeExhaust.getBindingContext());
131
132 return analyzeExhaust;
133 }
134
135 public static AnalyzeExhaust analyzeOneFileWithJavaIntegration(
136 JetFile file, List<AnalyzerScriptParameter> scriptParameters) {
137 return analyzeFilesWithJavaIntegration(file.getProject(), Collections.singleton(file), scriptParameters,
138 Predicates.<PsiFile>alwaysTrue());
139 }
140
141 public static AnalyzeExhaust analyzeFilesWithJavaIntegrationAndCheckForErrors(
142 Project project,
143 Collection<JetFile> files,
144 List<AnalyzerScriptParameter> scriptParameters,
145 Predicate<PsiFile> filesToAnalyzeCompletely
146 ) {
147 for (JetFile file : files) {
148 AnalyzingUtils.checkForSyntacticErrors(file);
149 }
150
151 AnalyzeExhaust analyzeExhaust = analyzeFilesWithJavaIntegration(
152 project, files, scriptParameters, filesToAnalyzeCompletely, false);
153
154 AnalyzingUtils.throwExceptionOnErrors(analyzeExhaust.getBindingContext());
155
156 return analyzeExhaust;
157 }
158
159 public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
160 Project project,
161 Collection<JetFile> files,
162 List<AnalyzerScriptParameter> scriptParameters,
163 Predicate<PsiFile> filesToAnalyzeCompletely
164 ) {
165 return analyzeFilesWithJavaIntegration(
166 project, files, scriptParameters, filesToAnalyzeCompletely, false);
167 }
168
169 public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
170 Project project, Collection<JetFile> files, List<AnalyzerScriptParameter> scriptParameters, Predicate<PsiFile> filesToAnalyzeCompletely,
171 boolean storeContextForBodiesResolve) {
172 BindingTraceContext bindingTraceContext = new BindingTraceContext();
173
174 return analyzeFilesWithJavaIntegration(project, files, bindingTraceContext, scriptParameters, filesToAnalyzeCompletely,
175 storeContextForBodiesResolve);
176 }
177
178 public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
179 Project project,
180 Collection<JetFile> files,
181 BindingTrace trace,
182 List<AnalyzerScriptParameter> scriptParameters,
183 Predicate<PsiFile> filesToAnalyzeCompletely,
184 boolean storeContextForBodiesResolve
185 ) {
186 ModuleDescriptorImpl owner = createJavaModule("<module>");
187
188 TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(
189 filesToAnalyzeCompletely, false, false, scriptParameters);
190
191 InjectorForTopDownAnalyzerForJvm injector = new InjectorForTopDownAnalyzerForJvm(
192 project, topDownAnalysisParameters,
193 new ObservableBindingTrace(trace), owner);
194 owner.setModuleConfiguration(injector.getJavaBridgeConfiguration());
195 try {
196 injector.getTopDownAnalyzer().analyzeFiles(files, scriptParameters);
197 BodiesResolveContext bodiesResolveContext = storeContextForBodiesResolve ?
198 new CachedBodiesResolveContext(injector.getTopDownAnalysisContext()) :
199 null;
200 return AnalyzeExhaust.success(trace.getBindingContext(), bodiesResolveContext, owner);
201 } finally {
202 injector.destroy();
203 }
204 }
205
206 @NotNull
207 public static ModuleDescriptorImpl createJavaModule(@NotNull String name) {
208 return new ModuleDescriptorImpl(Name.special(name), JavaBridgeConfiguration.ALL_JAVA_IMPORTS, JavaToKotlinClassMap.getInstance());
209 }
210 }