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 017package org.jetbrains.jet.lang.resolve.java; 018 019import com.google.common.base.Predicate; 020import com.google.common.base.Predicates; 021import com.intellij.openapi.project.Project; 022import com.intellij.psi.PsiFile; 023import org.jetbrains.annotations.NotNull; 024import org.jetbrains.jet.analyzer.AnalyzeExhaust; 025import org.jetbrains.jet.analyzer.AnalyzerFacade; 026import org.jetbrains.jet.analyzer.AnalyzerFacadeForEverything; 027import org.jetbrains.jet.di.InjectorForJavaDescriptorResolver; 028import org.jetbrains.jet.di.InjectorForTopDownAnalyzerForJvm; 029import org.jetbrains.jet.lang.ModuleConfiguration; 030import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; 031import org.jetbrains.jet.lang.descriptors.ModuleDescriptorImpl; 032import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; 033import org.jetbrains.jet.lang.psi.JetFile; 034import org.jetbrains.jet.lang.resolve.*; 035import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; 036import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory; 037import org.jetbrains.jet.lang.resolve.lazy.storage.LockBasedStorageManager; 038import org.jetbrains.jet.lang.resolve.name.FqName; 039import org.jetbrains.jet.lang.resolve.name.Name; 040import org.jetbrains.jet.lang.resolve.scopes.JetScope; 041import org.jetbrains.jet.lang.resolve.scopes.WritableScope; 042import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; 043 044import java.util.Collection; 045import java.util.Collections; 046import java.util.List; 047 048public 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}