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