Fix getting ModuleResolver by element for script files

Fixes EA-105435 (some isntances)
JavaResolveExtension: refactor API
This commit is contained in:
Pavel V. Talanov
2017-09-18 19:46:29 +03:00
parent 2af0bf4c71
commit c030a047aa
7 changed files with 42 additions and 43 deletions
@@ -39,7 +39,7 @@ import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.resolve.scopes.MemberScope
@JvmOverloads
fun PsiMethod.getJavaMethodDescriptor(resolutionFacade: ResolutionFacade? = null): FunctionDescriptor? {
fun PsiMethod.getJavaMethodDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): FunctionDescriptor? {
val method = originalElement as? PsiMethod ?: return null
if (method.containingClass == null || !Name.isValidIdentifier(method.name)) return null
val resolver = method.getJavaDescriptorResolver(resolutionFacade)
@@ -50,19 +50,19 @@ fun PsiMethod.getJavaMethodDescriptor(resolutionFacade: ResolutionFacade? = null
}
@JvmOverloads
fun PsiClass.getJavaClassDescriptor(resolutionFacade: ResolutionFacade? = null): ClassDescriptor? {
fun PsiClass.getJavaClassDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): ClassDescriptor? {
val psiClass = originalElement as? PsiClass ?: return null
return psiClass.getJavaDescriptorResolver(resolutionFacade)?.resolveClass(JavaClassImpl(psiClass))
}
@JvmOverloads
fun PsiField.getJavaFieldDescriptor(resolutionFacade: ResolutionFacade? = null): PropertyDescriptor? {
fun PsiField.getJavaFieldDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): PropertyDescriptor? {
val field = originalElement as? PsiField ?: return null
return field.getJavaDescriptorResolver(resolutionFacade)?.resolveField(JavaFieldImpl(field))
}
@JvmOverloads
fun PsiMember.getJavaMemberDescriptor(resolutionFacade: ResolutionFacade? = null): DeclarationDescriptor? {
fun PsiMember.getJavaMemberDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): DeclarationDescriptor? {
return when (this) {
is PsiClass -> getJavaClassDescriptor(resolutionFacade)
is PsiMethod -> getJavaMethodDescriptor(resolutionFacade)
@@ -72,19 +72,19 @@ fun PsiMember.getJavaMemberDescriptor(resolutionFacade: ResolutionFacade? = null
}
@JvmOverloads
fun PsiMember.getJavaOrKotlinMemberDescriptor(resolutionFacade: ResolutionFacade? = null): DeclarationDescriptor? {
fun PsiMember.getJavaOrKotlinMemberDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): DeclarationDescriptor? {
val callable = unwrapped
return when (callable) {
is PsiMember -> getJavaMemberDescriptor(resolutionFacade)
is KtDeclaration -> {
val descriptor = resolutionFacade?.resolveToDescriptor(callable) ?: callable.unsafeResolveToDescriptor()
val descriptor = resolutionFacade.resolveToDescriptor(callable)
if (descriptor is ClassDescriptor && this is PsiMethod) descriptor.unsubstitutedPrimaryConstructor else descriptor
}
else -> null
}
}
fun PsiParameter.getParameterDescriptor(resolutionFacade: ResolutionFacade? = null): ValueParameterDescriptor? {
fun PsiParameter.getParameterDescriptor(resolutionFacade: ResolutionFacade = javaResolutionFacade()): ValueParameterDescriptor? {
val method = declarationScope as? PsiMethod ?: return null
val methodDescriptor = method.getJavaMethodDescriptor(resolutionFacade) ?: return null
return methodDescriptor.valueParameters[parameterIndex()]
@@ -104,19 +104,8 @@ fun PsiClass.resolveToDescriptor(
} as? ClassDescriptor
}
private fun PsiElement.getJavaDescriptorResolver(resolutionFacade: ResolutionFacade?): JavaDescriptorResolver? {
if (resolutionFacade != null) {
return resolutionFacade.tryGetFrontendService(this, JavaDescriptorResolver::class.java)
}
else {
//TODO_R: should this work in scripts?
if (!ProjectRootsUtil.isInProjectOrLibraryClassFile(this)) return null
val cacheService = KotlinCacheService.getInstance(project)
val moduleInfo = this.getNullableModuleInfo() ?: return null
@Suppress("DEPRECATION")
return (cacheService as? KotlinCacheServiceImpl)?.tryGetProjectService(JvmPlatform, moduleInfo, JavaDescriptorResolver::class.java)
}
private fun PsiElement.getJavaDescriptorResolver(resolutionFacade: ResolutionFacade): JavaDescriptorResolver? {
return resolutionFacade.tryGetFrontendService(this, JavaDescriptorResolver::class.java)
}
private fun JavaDescriptorResolver.resolveMethod(method: JavaMethod): FunctionDescriptor? {
@@ -151,4 +140,7 @@ private fun <T : DeclarationDescriptorWithSource> Collection<T>.findByJavaElemen
false
}
}
}
}
fun PsiElement.javaResolutionFacade() =
KotlinCacheService.getInstance(project).getResolutionFacadeByFile(this.containingFile, JvmPlatform)
@@ -154,23 +154,12 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
)
}
@Deprecated("Use JetElement.getResolutionFacade(), please avoid introducing new usages")
fun <T : Any> getProjectService(platform: TargetPlatform, ideaModuleInfo: IdeaModuleInfo, serviceClass: Class<T>): T {
val settings = PlatformAnalysisSettings(platform, ideaModuleInfo.sdk, ideaModuleInfo.supportsAdditionalBuiltInsMembers())
return globalFacade(settings).resolverForModuleInfo(ideaModuleInfo).componentProvider.getService(serviceClass)
}
private fun IdeaModuleInfo.supportsAdditionalBuiltInsMembers(): Boolean {
return IDELanguageSettingsProvider
.getLanguageVersionSettings(this, project)
.supportsFeature(LanguageFeature.AdditionalBuiltInsMembers)
}
fun <T : Any> tryGetProjectService(platform: TargetPlatform, ideaModuleInfo: IdeaModuleInfo, serviceClass: Class<T>): T? {
val settings = PlatformAnalysisSettings(platform, ideaModuleInfo.sdk, ideaModuleInfo.supportsAdditionalBuiltInsMembers())
return globalFacade(settings).tryGetResolverForModuleInfo(ideaModuleInfo)?.componentProvider?.tryGetService(serviceClass)
}
private fun globalFacade(settings: PlatformAnalysisSettings) =
getOrBuildGlobalFacade(settings).facadeForModules
@@ -17,17 +17,20 @@
package org.jetbrains.kotlin.idea.caches.resolve
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.containers.SLRUCache
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.analyzer.EmptyResolverForProject
import org.jetbrains.kotlin.analyzer.ResolverForModule
import org.jetbrains.kotlin.context.GlobalContextImpl
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.CompositeBindingContext
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
internal class ProjectResolutionFacade(
private val debugString: String,
@@ -70,12 +73,20 @@ internal class ProjectResolutionFacade(
private val moduleResolverProvider: ModuleResolverProvider
get() = globalContext.storageManager.compute { cachedValue.value }
fun resolverForModuleInfo(moduleInfo: IdeaModuleInfo) = moduleResolverProvider.resolverForProject.resolverForModule(moduleInfo)
fun tryGetResolverForModuleInfo(moduleInfo: IdeaModuleInfo) = moduleResolverProvider.resolverForProject.tryGetResolverForModule(moduleInfo)
fun resolverForDescriptor(moduleDescriptor: ModuleDescriptor) = moduleResolverProvider.resolverForProject.resolverForModuleDescriptor(moduleDescriptor)
private val resolverForProject get() = moduleResolverProvider.resolverForProject
fun resolverForModuleInfo(moduleInfo: IdeaModuleInfo) = resolverForProject.resolverForModule(moduleInfo)
fun resolverForElement(element: PsiElement): ResolverForModule {
val infos = element.getModuleInfos()
return infos.firstNotNullResult { resolverForProject.tryGetResolverForModule(it) }
?: resolverForProject.diagnoseUnknownModuleInfo(infos)
}
fun resolverForDescriptor(moduleDescriptor: ModuleDescriptor) = resolverForProject.resolverForModuleDescriptor(moduleDescriptor)
fun findModuleDescriptor(ideaModuleInfo: IdeaModuleInfo): ModuleDescriptor {
return moduleResolverProvider.resolverForProject.descriptorForModule(ideaModuleInfo)
return resolverForProject.descriptorForModule(ideaModuleInfo)
}
private val analysisResults = CachedValuesManager.getManager(project).createCachedValue(
@@ -69,7 +69,7 @@ internal class ResolutionFacadeImpl(
?: getFrontendService(moduleInfo, AbsentDescriptorHandler::class.java).diagnoseDescriptorNotFound(declaration)
}
else {
val resolveSession = projectFacade.resolverForModuleInfo(declaration.getModuleInfo()).componentProvider.get<ResolveSession>()
val resolveSession = projectFacade.resolverForElement(declaration).componentProvider.get<ResolveSession>()
resolveSession.resolveToDescriptor(declaration)
}
}
@@ -81,11 +81,11 @@ internal class ResolutionFacadeImpl(
}
override fun <T : Any> getFrontendService(element: PsiElement, serviceClass: Class<T>): T {
return getFrontendService(element.getModuleInfo(), serviceClass)
return projectFacade.resolverForElement(element).componentProvider.getService(serviceClass)
}
override fun <T : Any> tryGetFrontendService(element: PsiElement, serviceClass: Class<T>): T? {
return element.getModuleInfos().firstNotNullResult { projectFacade.tryGetResolverForModuleInfo(it)?.componentProvider?.tryGetService(serviceClass) }
return projectFacade.resolverForElement(element).componentProvider.tryGetService(serviceClass)
}
fun <T : Any> getFrontendService(ideaModuleInfo: IdeaModuleInfo, serviceClass: Class<T>): T {