001 /* 002 * Copyright 2010-2016 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.jvm.functions.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.incremental.components.LookupLocation; 031 import org.jetbrains.kotlin.incremental.components.LookupTracker; 032 import org.jetbrains.kotlin.incremental.components.NoLookupLocation; 033 import org.jetbrains.kotlin.name.FqName; 034 import org.jetbrains.kotlin.name.Name; 035 import org.jetbrains.kotlin.psi.*; 036 import org.jetbrains.kotlin.resolve.*; 037 import org.jetbrains.kotlin.resolve.lazy.data.KtClassLikeInfo; 038 import org.jetbrains.kotlin.resolve.lazy.data.KtClassOrObjectInfo; 039 import org.jetbrains.kotlin.resolve.lazy.data.KtScriptInfo; 040 import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory; 041 import org.jetbrains.kotlin.resolve.lazy.declarations.PackageMemberDeclarationProvider; 042 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotations; 043 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationsContextImpl; 044 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor; 045 import org.jetbrains.kotlin.resolve.scopes.LexicalScope; 046 import org.jetbrains.kotlin.resolve.scopes.MemberScope; 047 import org.jetbrains.kotlin.storage.*; 048 049 import javax.inject.Inject; 050 import java.util.Collection; 051 import java.util.Collections; 052 import java.util.List; 053 054 public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext { 055 private final LazyResolveStorageManager storageManager; 056 private final ExceptionTracker exceptionTracker; 057 058 private final ModuleDescriptor module; 059 060 private final BindingTrace trace; 061 private final DeclarationProviderFactory declarationProviderFactory; 062 063 private final MemoizedFunctionToNullable<FqName, LazyPackageDescriptor> packages; 064 private final PackageFragmentProvider packageFragmentProvider; 065 066 private final MemoizedFunctionToNotNull<KtFile, LazyAnnotations> fileAnnotations; 067 private final MemoizedFunctionToNotNull<KtFile, LazyAnnotations> danglingAnnotations; 068 069 private KtImportsFactory jetImportFactory; 070 private AnnotationResolver annotationResolve; 071 private DescriptorResolver descriptorResolver; 072 private FunctionDescriptorResolver functionDescriptorResolver; 073 private TypeResolver typeResolver; 074 private LazyDeclarationResolver lazyDeclarationResolver; 075 private FileScopeProvider fileScopeProvider; 076 private DeclarationScopeProvider declarationScopeProvider; 077 private LookupTracker lookupTracker; 078 private LocalDescriptorResolver localDescriptorResolver; 079 private SupertypeLoopChecker supertypeLoopsResolver; 080 081 @Inject 082 public void setJetImportFactory(KtImportsFactory jetImportFactory) { 083 this.jetImportFactory = jetImportFactory; 084 } 085 086 @Inject 087 public void setAnnotationResolve(AnnotationResolver annotationResolve) { 088 this.annotationResolve = annotationResolve; 089 } 090 091 @Inject 092 public void setDescriptorResolver(DescriptorResolver descriptorResolver) { 093 this.descriptorResolver = descriptorResolver; 094 } 095 096 @Inject 097 public void setFunctionDescriptorResolver(FunctionDescriptorResolver functionDescriptorResolver) { 098 this.functionDescriptorResolver = functionDescriptorResolver; 099 } 100 101 @Inject 102 public void setTypeResolver(TypeResolver typeResolver) { 103 this.typeResolver = typeResolver; 104 } 105 106 @Inject 107 public void setLazyDeclarationResolver(LazyDeclarationResolver lazyDeclarationResolver) { 108 this.lazyDeclarationResolver = lazyDeclarationResolver; 109 } 110 111 @Inject 112 public void setFileScopeProvider(@NotNull FileScopeProvider fileScopeProvider) { 113 this.fileScopeProvider = fileScopeProvider; 114 } 115 116 @Inject 117 public void setDeclarationScopeProvider(@NotNull DeclarationScopeProviderImpl declarationScopeProvider) { 118 this.declarationScopeProvider = declarationScopeProvider; 119 } 120 121 @Inject 122 public void setLookupTracker(@NotNull LookupTracker lookupTracker) { 123 this.lookupTracker = lookupTracker; 124 } 125 126 // Only calls from injectors expected 127 @Deprecated 128 public ResolveSession( 129 @NotNull Project project, 130 @NotNull GlobalContext globalContext, 131 @NotNull ModuleDescriptor rootDescriptor, 132 @NotNull DeclarationProviderFactory declarationProviderFactory, 133 @NotNull BindingTrace delegationTrace 134 ) { 135 LockBasedLazyResolveStorageManager lockBasedLazyResolveStorageManager = 136 new LockBasedLazyResolveStorageManager(globalContext.getStorageManager()); 137 138 this.storageManager = lockBasedLazyResolveStorageManager; 139 this.exceptionTracker = globalContext.getExceptionTracker(); 140 this.trace = lockBasedLazyResolveStorageManager.createSafeTrace(delegationTrace); 141 this.module = rootDescriptor; 142 143 this.packages = 144 storageManager.createMemoizedFunctionWithNullableValues(new Function1<FqName, LazyPackageDescriptor>() { 145 @Override 146 @Nullable 147 public LazyPackageDescriptor invoke(FqName fqName) { 148 return createPackage(fqName); 149 } 150 }); 151 152 this.declarationProviderFactory = declarationProviderFactory; 153 154 this.packageFragmentProvider = new PackageFragmentProvider() { 155 @NotNull 156 @Override 157 public List<PackageFragmentDescriptor> getPackageFragments(@NotNull FqName fqName) { 158 return ContainerUtil.<PackageFragmentDescriptor>createMaybeSingletonList(getPackageFragment(fqName)); 159 } 160 161 @NotNull 162 @Override 163 public Collection<FqName> getSubPackagesOf( 164 @NotNull FqName fqName, @NotNull Function1<? super Name, Boolean> nameFilter 165 ) { 166 LazyPackageDescriptor packageDescriptor = getPackageFragment(fqName); 167 if (packageDescriptor == null) { 168 return Collections.emptyList(); 169 } 170 return packageDescriptor.getDeclarationProvider().getAllDeclaredSubPackages(nameFilter); 171 } 172 }; 173 174 fileAnnotations = storageManager.createMemoizedFunction(new Function1<KtFile, LazyAnnotations>() { 175 @Override 176 public LazyAnnotations invoke(KtFile file) { 177 return createAnnotations(file, file.getAnnotationEntries()); 178 } 179 }); 180 181 danglingAnnotations = storageManager.createMemoizedFunction(new Function1<KtFile, LazyAnnotations>() { 182 @Override 183 public LazyAnnotations invoke(KtFile file) { 184 return createAnnotations(file, file.getDanglingAnnotations()); 185 } 186 }); 187 } 188 189 private LazyAnnotations createAnnotations(KtFile file, List<KtAnnotationEntry> annotationEntries) { 190 LexicalScope scope = fileScopeProvider.getFileResolutionScope(file); 191 LazyAnnotationsContextImpl lazyAnnotationContext = 192 new LazyAnnotationsContextImpl(annotationResolve, storageManager, trace, scope); 193 return new LazyAnnotations(lazyAnnotationContext, annotationEntries); 194 } 195 196 @Override 197 @NotNull 198 public PackageFragmentProvider getPackageFragmentProvider() { 199 return packageFragmentProvider; 200 } 201 202 @Override 203 @Nullable 204 public LazyPackageDescriptor getPackageFragment(@NotNull FqName fqName) { 205 return packages.invoke(fqName); 206 } 207 208 @Nullable 209 private LazyPackageDescriptor createPackage(FqName fqName) { 210 PackageMemberDeclarationProvider provider = declarationProviderFactory.getPackageMemberDeclarationProvider(fqName); 211 if (provider == null) { 212 return null; 213 } 214 return new LazyPackageDescriptor(module, fqName, this, provider); 215 } 216 217 @NotNull 218 @Override 219 public ModuleDescriptor getModuleDescriptor() { 220 return module; 221 } 222 223 @NotNull 224 @Override 225 public LazyResolveStorageManager getStorageManager() { 226 return storageManager; 227 } 228 229 @NotNull 230 public ExceptionTracker getExceptionTracker() { 231 return exceptionTracker; 232 } 233 234 @Override 235 @NotNull 236 @ReadOnly 237 public Collection<ClassDescriptor> getTopLevelClassDescriptors(@NotNull FqName fqName, @NotNull final LookupLocation location) { 238 if (fqName.isRoot()) return Collections.emptyList(); 239 240 PackageMemberDeclarationProvider provider = declarationProviderFactory.getPackageMemberDeclarationProvider(fqName.parent()); 241 if (provider == null) return Collections.emptyList(); 242 243 return ContainerUtil.mapNotNull( 244 provider.getClassOrObjectDeclarations(fqName.shortName()), 245 new Function<KtClassLikeInfo, ClassDescriptor>() { 246 @Override 247 public ClassDescriptor fun(KtClassLikeInfo classLikeInfo) { 248 if (classLikeInfo instanceof KtClassOrObjectInfo) { 249 //noinspection RedundantCast 250 return getClassDescriptor(((KtClassOrObjectInfo) classLikeInfo).getCorrespondingClassOrObject(), location); 251 } 252 else if (classLikeInfo instanceof KtScriptInfo) { 253 return getScriptDescriptor(((KtScriptInfo) classLikeInfo).getScript()); 254 } 255 else { 256 throw new IllegalStateException( 257 "Unexpected " + classLikeInfo + " of type " + classLikeInfo.getClass().getName() 258 ); 259 } 260 } 261 } 262 ); 263 } 264 265 @Override 266 @NotNull 267 public ClassDescriptor getClassDescriptor(@NotNull KtClassOrObject classOrObject, @NotNull LookupLocation location) { 268 return lazyDeclarationResolver.getClassDescriptor(classOrObject, location); 269 } 270 271 @NotNull 272 public ScriptDescriptor getScriptDescriptor(@NotNull KtScript script) { 273 return lazyDeclarationResolver.getScriptDescriptor(script, NoLookupLocation.FOR_SCRIPT); 274 } 275 276 @Override 277 @NotNull 278 public BindingContext getBindingContext() { 279 return trace.getBindingContext(); 280 } 281 282 @Override 283 @NotNull 284 public BindingTrace getTrace() { 285 return trace; 286 } 287 288 @Override 289 @NotNull 290 public DeclarationProviderFactory getDeclarationProviderFactory() { 291 return declarationProviderFactory; 292 } 293 294 @Override 295 @NotNull 296 public DeclarationDescriptor resolveToDescriptor(@NotNull KtDeclaration declaration) { 297 if (!areDescriptorsCreatedForDeclaration(declaration)) { 298 throw new IllegalStateException( 299 "No descriptors are created for declarations of type " + declaration.getClass().getSimpleName() 300 + "\n. Change the caller accordingly" 301 ); 302 } 303 if (!KtPsiUtil.isLocal(declaration)) { 304 return lazyDeclarationResolver.resolveToDescriptor(declaration); 305 } 306 return localDescriptorResolver.resolveLocalDeclaration(declaration); 307 } 308 309 public static boolean areDescriptorsCreatedForDeclaration(@NotNull KtDeclaration declaration) { 310 return !(declaration instanceof KtAnonymousInitializer || declaration instanceof KtDestructuringDeclaration); 311 } 312 313 @NotNull 314 public Annotations getFileAnnotations(@NotNull KtFile file) { 315 return fileAnnotations.invoke(file); 316 } 317 318 @NotNull 319 public Annotations getDanglingAnnotations(@NotNull KtFile file) { 320 return danglingAnnotations.invoke(file); 321 } 322 323 @NotNull 324 private List<LazyPackageDescriptor> getAllPackages() { 325 LazyPackageDescriptor rootPackage = getPackageFragment(FqName.ROOT); 326 assert rootPackage != null : "Root package must be initialized"; 327 328 return collectAllPackages(Lists.<LazyPackageDescriptor>newArrayList(), rootPackage); 329 } 330 331 @NotNull 332 private List<LazyPackageDescriptor> collectAllPackages( 333 @NotNull List<LazyPackageDescriptor> result, 334 @NotNull LazyPackageDescriptor current 335 ) { 336 result.add(current); 337 for (FqName subPackage : packageFragmentProvider.getSubPackagesOf(current.getFqName(), MemberScope.Companion.getALL_NAME_FILTER())) { 338 LazyPackageDescriptor fragment = getPackageFragment(subPackage); 339 assert fragment != null : "Couldn't find fragment for " + subPackage; 340 collectAllPackages(result, fragment); 341 } 342 return result; 343 } 344 345 @Override 346 public void forceResolveAll() { 347 for (LazyPackageDescriptor lazyPackage : getAllPackages()) { 348 ForceResolveUtil.forceResolveAllContents(lazyPackage); 349 } 350 } 351 352 @NotNull 353 public KtImportsFactory getJetImportsFactory() { 354 return jetImportFactory; 355 } 356 357 @Override 358 @NotNull 359 public AnnotationResolver getAnnotationResolver() { 360 return annotationResolve; 361 } 362 363 @Override 364 @NotNull 365 public DescriptorResolver getDescriptorResolver() { 366 return descriptorResolver; 367 } 368 369 @Override 370 @NotNull 371 public TypeResolver getTypeResolver() { 372 return typeResolver; 373 } 374 375 @NotNull 376 @Override 377 public FunctionDescriptorResolver getFunctionDescriptorResolver() { 378 return functionDescriptorResolver; 379 } 380 381 @NotNull 382 @Override 383 public DeclarationScopeProvider getDeclarationScopeProvider() { 384 return declarationScopeProvider; 385 } 386 387 @Override 388 @NotNull 389 public FileScopeProvider getFileScopeProvider() { 390 return fileScopeProvider; 391 } 392 393 @NotNull 394 @Override 395 public LookupTracker getLookupTracker() { 396 return lookupTracker; 397 } 398 399 @NotNull 400 @Override 401 public SupertypeLoopChecker getSupertypeLoopChecker() { 402 return supertypeLoopsResolver; 403 } 404 405 @Inject 406 public void setSupertypeLoopsResolver(@NotNull SupertypeLoopChecker supertypeLoopsResolver) { 407 this.supertypeLoopsResolver = supertypeLoopsResolver; 408 } 409 410 @Inject 411 public void setLocalDescriptorResolver(@NotNull LocalDescriptorResolver localDescriptorResolver) { 412 this.localDescriptorResolver = localDescriptorResolver; 413 } 414 }