001 /* 002 * Copyright 2010-2015 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.kotlin.resolve.lazy; 018 019 import com.google.common.collect.Lists; 020 import com.intellij.openapi.project.Project; 021 import com.intellij.util.Function; 022 import com.intellij.util.containers.ContainerUtil; 023 import kotlin.Function1; 024 import org.jetbrains.annotations.NotNull; 025 import org.jetbrains.annotations.Nullable; 026 import org.jetbrains.annotations.ReadOnly; 027 import org.jetbrains.kotlin.context.GlobalContext; 028 import org.jetbrains.kotlin.descriptors.*; 029 import org.jetbrains.kotlin.descriptors.annotations.Annotations; 030 import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl; 031 import org.jetbrains.kotlin.name.FqName; 032 import org.jetbrains.kotlin.name.Name; 033 import org.jetbrains.kotlin.psi.*; 034 import org.jetbrains.kotlin.resolve.*; 035 import org.jetbrains.kotlin.resolve.lazy.data.JetClassLikeInfo; 036 import org.jetbrains.kotlin.resolve.lazy.data.JetScriptInfo; 037 import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory; 038 import org.jetbrains.kotlin.resolve.lazy.declarations.PackageMemberDeclarationProvider; 039 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotations; 040 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationsContextImpl; 041 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor; 042 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyScriptDescriptor; 043 import org.jetbrains.kotlin.resolve.scopes.JetScope; 044 import org.jetbrains.kotlin.storage.*; 045 046 import javax.inject.Inject; 047 import java.util.Collection; 048 import java.util.Collections; 049 import java.util.List; 050 051 public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext { 052 private final LazyResolveStorageManager storageManager; 053 private final ExceptionTracker exceptionTracker; 054 055 private final ModuleDescriptor module; 056 057 private final BindingTrace trace; 058 private final DeclarationProviderFactory declarationProviderFactory; 059 060 private final MemoizedFunctionToNullable<FqName, LazyPackageDescriptor> packages; 061 private final PackageFragmentProvider packageFragmentProvider; 062 063 private final MemoizedFunctionToNotNull<JetScript, LazyScriptDescriptor> scriptDescriptors; 064 065 private final MemoizedFunctionToNotNull<JetFile, LazyAnnotations> fileAnnotations; 066 private final MemoizedFunctionToNotNull<JetFile, LazyAnnotations> danglingAnnotations; 067 068 private ScopeProvider scopeProvider; 069 070 private JetImportsFactory jetImportFactory; 071 private AnnotationResolver annotationResolve; 072 private DescriptorResolver descriptorResolver; 073 private TypeResolver typeResolver; 074 private QualifiedExpressionResolver qualifiedExpressionResolver; 075 private ScriptBodyResolver scriptBodyResolver; 076 private LazyDeclarationResolver lazyDeclarationResolver; 077 078 @Inject 079 public void setJetImportFactory(JetImportsFactory jetImportFactory) { 080 this.jetImportFactory = jetImportFactory; 081 } 082 083 @Inject 084 public void setAnnotationResolve(AnnotationResolver annotationResolve) { 085 this.annotationResolve = annotationResolve; 086 } 087 088 @Inject 089 public void setDescriptorResolver(DescriptorResolver descriptorResolver) { 090 this.descriptorResolver = descriptorResolver; 091 } 092 093 @Inject 094 public void setTypeResolver(TypeResolver typeResolver) { 095 this.typeResolver = typeResolver; 096 } 097 098 @Inject 099 public void setQualifiedExpressionResolver(QualifiedExpressionResolver qualifiedExpressionResolver) { 100 this.qualifiedExpressionResolver = qualifiedExpressionResolver; 101 } 102 103 @Inject 104 public void setScopeProvider(ScopeProvider scopeProvider) { 105 this.scopeProvider = scopeProvider; 106 } 107 108 @Inject 109 public void setScriptBodyResolver(ScriptBodyResolver scriptBodyResolver) { 110 this.scriptBodyResolver = scriptBodyResolver; 111 } 112 113 @Inject 114 public void setLazyDeclarationResolver(LazyDeclarationResolver lazyDeclarationResolver) { 115 this.lazyDeclarationResolver = lazyDeclarationResolver; 116 } 117 118 // Only calls from injectors expected 119 @Deprecated 120 public ResolveSession( 121 @NotNull Project project, 122 @NotNull GlobalContext globalContext, 123 @NotNull ModuleDescriptorImpl rootDescriptor, 124 @NotNull DeclarationProviderFactory declarationProviderFactory, 125 @NotNull BindingTrace delegationTrace 126 ) { 127 LockBasedLazyResolveStorageManager lockBasedLazyResolveStorageManager = 128 new LockBasedLazyResolveStorageManager(globalContext.getStorageManager()); 129 130 this.storageManager = lockBasedLazyResolveStorageManager; 131 this.exceptionTracker = globalContext.getExceptionTracker(); 132 this.trace = lockBasedLazyResolveStorageManager.createSafeTrace(delegationTrace); 133 this.module = rootDescriptor; 134 135 this.packages = 136 storageManager.createMemoizedFunctionWithNullableValues(new MemoizedFunctionToNullable<FqName, LazyPackageDescriptor>() { 137 @Nullable 138 @Override 139 public LazyPackageDescriptor invoke(FqName fqName) { 140 return createPackage(fqName); 141 } 142 }); 143 144 this.declarationProviderFactory = declarationProviderFactory; 145 146 this.packageFragmentProvider = new PackageFragmentProvider() { 147 @NotNull 148 @Override 149 public List<PackageFragmentDescriptor> getPackageFragments(@NotNull FqName fqName) { 150 return ContainerUtil.<PackageFragmentDescriptor>createMaybeSingletonList(getPackageFragment(fqName)); 151 } 152 153 @NotNull 154 @Override 155 public Collection<FqName> getSubPackagesOf( 156 @NotNull FqName fqName, @NotNull Function1<? super Name, ? extends Boolean> nameFilter 157 ) { 158 LazyPackageDescriptor packageDescriptor = getPackageFragment(fqName); 159 if (packageDescriptor == null) { 160 return Collections.emptyList(); 161 } 162 return packageDescriptor.getDeclarationProvider().getAllDeclaredSubPackages(); 163 } 164 }; 165 166 this.scriptDescriptors = storageManager.createMemoizedFunction( 167 new Function1<JetScript, LazyScriptDescriptor>() { 168 @Override 169 public LazyScriptDescriptor invoke(JetScript script) { 170 return new LazyScriptDescriptor( 171 ResolveSession.this, 172 scriptBodyResolver, 173 script, 174 ScriptHeaderResolver.getScriptPriority(script) 175 ); 176 } 177 } 178 ); 179 180 fileAnnotations = storageManager.createMemoizedFunction(new Function1<JetFile, LazyAnnotations>() { 181 @Override 182 public LazyAnnotations invoke(JetFile file) { 183 return createAnnotations(file, file.getAnnotationEntries()); 184 } 185 }); 186 187 danglingAnnotations = storageManager.createMemoizedFunction(new Function1<JetFile, LazyAnnotations>() { 188 @Override 189 public LazyAnnotations invoke(JetFile file) { 190 return createAnnotations(file, file.getDanglingAnnotations()); 191 } 192 }); 193 } 194 195 private LazyAnnotations createAnnotations(JetFile file, List<JetAnnotationEntry> annotationEntries) { 196 JetScope scope = getScopeProvider().getFileScope(file); 197 LazyAnnotationsContextImpl lazyAnnotationContext = new LazyAnnotationsContextImpl(annotationResolve, storageManager, trace, scope); 198 return new LazyAnnotations(lazyAnnotationContext, annotationEntries); 199 } 200 201 @Override 202 @NotNull 203 public PackageFragmentProvider getPackageFragmentProvider() { 204 return packageFragmentProvider; 205 } 206 207 @Override 208 @Nullable 209 public LazyPackageDescriptor getPackageFragment(@NotNull FqName fqName) { 210 return packages.invoke(fqName); 211 } 212 213 @Nullable 214 private LazyPackageDescriptor createPackage(FqName fqName) { 215 if (!fqName.isRoot() && getPackageFragment(fqName.parent()) == null) { 216 return null; 217 } 218 PackageMemberDeclarationProvider provider = declarationProviderFactory.getPackageMemberDeclarationProvider(fqName); 219 if (provider == null) { 220 return null; 221 } 222 return new LazyPackageDescriptor(module, fqName, this, provider); 223 } 224 225 @NotNull 226 @Override 227 public ModuleDescriptor getModuleDescriptor() { 228 return module; 229 } 230 231 @NotNull 232 @Override 233 public LazyResolveStorageManager getStorageManager() { 234 return storageManager; 235 } 236 237 @NotNull 238 public ExceptionTracker getExceptionTracker() { 239 return exceptionTracker; 240 } 241 242 @Override 243 @NotNull 244 @ReadOnly 245 public Collection<ClassDescriptor> getTopLevelClassDescriptors(@NotNull FqName fqName) { 246 if (fqName.isRoot()) return Collections.emptyList(); 247 248 PackageMemberDeclarationProvider provider = declarationProviderFactory.getPackageMemberDeclarationProvider(fqName.parent()); 249 if (provider == null) return Collections.emptyList(); 250 251 return ContainerUtil.mapNotNull( 252 provider.getClassOrObjectDeclarations(fqName.shortName()), 253 new Function<JetClassLikeInfo, ClassDescriptor>() { 254 @Override 255 public ClassDescriptor fun(JetClassLikeInfo classLikeInfo) { 256 if (classLikeInfo instanceof JetScriptInfo) { 257 return getClassDescriptorForScript(((JetScriptInfo) classLikeInfo).getScript()); 258 } 259 JetClassOrObject classOrObject = classLikeInfo.getCorrespondingClassOrObject(); 260 if (classOrObject == null) return null; 261 return getClassDescriptor(classOrObject); 262 } 263 } 264 ); 265 } 266 267 @Override 268 @NotNull 269 public ClassDescriptor getClassDescriptor(@NotNull JetClassOrObject classOrObject) { 270 return lazyDeclarationResolver.getClassDescriptor(classOrObject); 271 } 272 273 @NotNull 274 public ClassDescriptor getClassDescriptorForScript(@NotNull JetScript script) { 275 JetScope resolutionScope = lazyDeclarationResolver.resolutionScopeToResolveDeclaration(script); 276 FqName fqName = ScriptNameUtil.classNameForScript(script); 277 ClassifierDescriptor classifier = resolutionScope.getClassifier(fqName.shortName()); 278 assert classifier != null : "No descriptor for " + fqName + " in file " + script.getContainingFile(); 279 return (ClassDescriptor) classifier; 280 } 281 282 @Override 283 @NotNull 284 public ScriptDescriptor getScriptDescriptor(@NotNull JetScript script) { 285 return scriptDescriptors.invoke(script); 286 } 287 288 @Override 289 @NotNull 290 public BindingContext getBindingContext() { 291 return trace.getBindingContext(); 292 } 293 294 @Override 295 @NotNull 296 public BindingTrace getTrace() { 297 return trace; 298 } 299 300 @Override 301 @NotNull 302 public DeclarationProviderFactory getDeclarationProviderFactory() { 303 return declarationProviderFactory; 304 } 305 306 @Override 307 @NotNull 308 public DeclarationDescriptor resolveToDescriptor(@NotNull JetDeclaration declaration) { 309 return lazyDeclarationResolver.resolveToDescriptor(declaration); 310 } 311 312 @NotNull 313 public Annotations getFileAnnotations(@NotNull JetFile file) { 314 return fileAnnotations.invoke(file); 315 } 316 317 @NotNull 318 public Annotations getDanglingAnnotations(@NotNull JetFile file) { 319 return danglingAnnotations.invoke(file); 320 } 321 322 @NotNull 323 private List<LazyPackageDescriptor> getAllPackages() { 324 LazyPackageDescriptor rootPackage = getPackageFragment(FqName.ROOT); 325 assert rootPackage != null : "Root package must be initialized"; 326 327 return collectAllPackages(Lists.<LazyPackageDescriptor>newArrayList(), rootPackage); 328 } 329 330 @NotNull 331 private List<LazyPackageDescriptor> collectAllPackages( 332 @NotNull List<LazyPackageDescriptor> result, 333 @NotNull LazyPackageDescriptor current 334 ) { 335 result.add(current); 336 for (FqName subPackage : packageFragmentProvider.getSubPackagesOf(current.getFqName(), JetScope.ALL_NAME_FILTER)) { 337 LazyPackageDescriptor fragment = getPackageFragment(subPackage); 338 assert fragment != null : "Couldn't find fragment for " + subPackage; 339 collectAllPackages(result, fragment); 340 } 341 return result; 342 } 343 344 @Override 345 public void forceResolveAll() { 346 for (LazyPackageDescriptor lazyPackage : getAllPackages()) { 347 ForceResolveUtil.forceResolveAllContents(lazyPackage); 348 } 349 } 350 351 @Override 352 @NotNull 353 public ScopeProvider getScopeProvider() { 354 return scopeProvider; 355 } 356 357 @NotNull 358 public JetImportsFactory getJetImportsFactory() { 359 return jetImportFactory; 360 } 361 362 @Override 363 @NotNull 364 public AnnotationResolver getAnnotationResolver() { 365 return annotationResolve; 366 } 367 368 @Override 369 @NotNull 370 public DescriptorResolver getDescriptorResolver() { 371 return descriptorResolver; 372 } 373 374 @Override 375 @NotNull 376 public TypeResolver getTypeResolver() { 377 return typeResolver; 378 } 379 380 @NotNull 381 public QualifiedExpressionResolver getQualifiedExpressionResolver() { 382 return qualifiedExpressionResolver; 383 } 384 }