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.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.MemberScope; 046 import org.jetbrains.kotlin.resolve.scopes.LexicalScope; 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 FileScopeProviderImpl 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 (!KtPsiUtil.isLocal(declaration)) { 298 return lazyDeclarationResolver.resolveToDescriptor(declaration); 299 } 300 return localDescriptorResolver.resolveLocalDeclaration(declaration); 301 } 302 303 @NotNull 304 public Annotations getFileAnnotations(@NotNull KtFile file) { 305 return fileAnnotations.invoke(file); 306 } 307 308 @NotNull 309 public Annotations getDanglingAnnotations(@NotNull KtFile file) { 310 return danglingAnnotations.invoke(file); 311 } 312 313 @NotNull 314 private List<LazyPackageDescriptor> getAllPackages() { 315 LazyPackageDescriptor rootPackage = getPackageFragment(FqName.ROOT); 316 assert rootPackage != null : "Root package must be initialized"; 317 318 return collectAllPackages(Lists.<LazyPackageDescriptor>newArrayList(), rootPackage); 319 } 320 321 @NotNull 322 private List<LazyPackageDescriptor> collectAllPackages( 323 @NotNull List<LazyPackageDescriptor> result, 324 @NotNull LazyPackageDescriptor current 325 ) { 326 result.add(current); 327 for (FqName subPackage : packageFragmentProvider.getSubPackagesOf(current.getFqName(), MemberScope.Companion.getALL_NAME_FILTER())) { 328 LazyPackageDescriptor fragment = getPackageFragment(subPackage); 329 assert fragment != null : "Couldn't find fragment for " + subPackage; 330 collectAllPackages(result, fragment); 331 } 332 return result; 333 } 334 335 @Override 336 public void forceResolveAll() { 337 for (LazyPackageDescriptor lazyPackage : getAllPackages()) { 338 ForceResolveUtil.forceResolveAllContents(lazyPackage); 339 } 340 } 341 342 @NotNull 343 public KtImportsFactory getJetImportsFactory() { 344 return jetImportFactory; 345 } 346 347 @Override 348 @NotNull 349 public AnnotationResolver getAnnotationResolver() { 350 return annotationResolve; 351 } 352 353 @Override 354 @NotNull 355 public DescriptorResolver getDescriptorResolver() { 356 return descriptorResolver; 357 } 358 359 @Override 360 @NotNull 361 public TypeResolver getTypeResolver() { 362 return typeResolver; 363 } 364 365 @NotNull 366 @Override 367 public FunctionDescriptorResolver getFunctionDescriptorResolver() { 368 return functionDescriptorResolver; 369 } 370 371 @NotNull 372 @Override 373 public DeclarationScopeProvider getDeclarationScopeProvider() { 374 return declarationScopeProvider; 375 } 376 377 @Override 378 @NotNull 379 public FileScopeProvider getFileScopeProvider() { 380 return fileScopeProvider; 381 } 382 383 @NotNull 384 @Override 385 public LookupTracker getLookupTracker() { 386 return lookupTracker; 387 } 388 389 @NotNull 390 @Override 391 public SupertypeLoopChecker getSupertypeLoopChecker() { 392 return supertypeLoopsResolver; 393 } 394 395 @Inject 396 public void setSupertypeLoopsResolver(@NotNull SupertypeLoopChecker supertypeLoopsResolver) { 397 this.supertypeLoopsResolver = supertypeLoopsResolver; 398 } 399 400 @Inject 401 public void setLocalDescriptorResolver(@NotNull LocalDescriptorResolver localDescriptorResolver) { 402 this.localDescriptorResolver = localDescriptorResolver; 403 } 404 }