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