Merge ResolutionFacadeImpl and KotlinResolveCache, rewrite JavaResolveExtension

This commit is contained in:
Pavel V. Talanov
2015-08-05 12:34:20 +03:00
parent 94431bc3fa
commit d09f4a4dbb
17 changed files with 194 additions and 283 deletions
@@ -16,8 +16,6 @@
package org.jetbrains.kotlin.container package org.jetbrains.kotlin.container
import kotlin.properties.ReadOnlyProperty
public fun createContainer(id: String, init: StorageComponentContainer.() -> Unit): StorageComponentContainer { public fun createContainer(id: String, init: StorageComponentContainer.() -> Unit): StorageComponentContainer {
val c = StorageComponentContainer(id) val c = StorageComponentContainer(id)
c.init() c.init()
@@ -30,7 +28,12 @@ public inline fun <reified T> StorageComponentContainer.useImpl() {
} }
public inline fun <reified T> ComponentProvider.get(): T { public inline fun <reified T> ComponentProvider.get(): T {
return resolve(javaClass<T>())!!.getValue() as T return getService(javaClass<T>())
}
@suppress("UNCHECKED_CAST")
public fun <T> ComponentProvider.getService(request: Class<T>): T {
return resolve(request)!!.getValue() as T
} }
public fun StorageComponentContainer.useInstance(instance: Any) { public fun StorageComponentContainer.useInstance(instance: Any) {
@@ -38,5 +41,5 @@ public fun StorageComponentContainer.useInstance(instance: Any) {
} }
public inline fun <reified T> ComponentProvider.get(thisRef: Any?, desc: PropertyMetadata): T { public inline fun <reified T> ComponentProvider.get(thisRef: Any?, desc: PropertyMetadata): T {
return resolve(javaClass<T>())!!.getValue() as T return getService(javaClass<T>())
} }
@@ -17,7 +17,7 @@
package org.jetbrains.kotlin.idea.analysis package org.jetbrains.kotlin.idea.analysis
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.getService import org.jetbrains.kotlin.idea.caches.resolve.frontendService
import org.jetbrains.kotlin.psi.JetExpression import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
@@ -36,7 +36,7 @@ public fun JetExpression.computeTypeInfoInContext(
dataFlowInfo: DataFlowInfo = DataFlowInfo.EMPTY, dataFlowInfo: DataFlowInfo = DataFlowInfo.EMPTY,
expectedType: JetType = TypeUtils.NO_EXPECTED_TYPE expectedType: JetType = TypeUtils.NO_EXPECTED_TYPE
): JetTypeInfo { ): JetTypeInfo {
return getResolutionFacade().getService<ExpressionTypingServices>(this).getTypeInfo(scope, this, expectedType, dataFlowInfo, trace) return getResolutionFacade().frontendService<ExpressionTypingServices>(this).getTypeInfo(scope, this, expectedType, dataFlowInfo, trace)
} }
jvmOverloads jvmOverloads
@@ -16,41 +16,24 @@
package org.jetbrains.kotlin.idea.caches.resolve package org.jetbrains.kotlin.idea.caches.resolve
import com.intellij.openapi.project.Project
import com.intellij.psi.* import com.intellij.psi.*
import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.load.java.structure.impl.* import org.jetbrains.kotlin.load.java.structure.impl.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.resolve.scopes.JetScope
public object JavaResolveExtension : CacheExtension<(PsiElement) -> Pair<JavaDescriptorResolver, BindingContext>> { private fun PsiElement.getJavaDescriptorResolver(): JavaDescriptorResolver {
override val platform: TargetPlatform = JvmPlatform @suppress("DEPRECATED_SYMBOL_WITH_MESSAGE")
return KotlinCacheService.getInstance(getProject()).getGlobalFacade(JvmPlatform).frontendService<JavaDescriptorResolver>(this)
override fun getData(resolverProvider: ModuleResolverProvider): (PsiElement) -> Pair<JavaDescriptorResolver, BindingContext> {
return {
val componentProvider = resolverProvider.resolverByModule(it.getModuleInfo()).componentProvider
Pair(componentProvider.get<JavaDescriptorResolver>(), componentProvider.get<BindingTrace>().getBindingContext())
}
}
public fun getResolver(project: Project, element: PsiElement): JavaDescriptorResolver =
KotlinCacheService.getInstance(project)[this](element).first
public fun getContext(project: Project, element: PsiElement): BindingContext =
KotlinCacheService.getInstance(project)[this](element).second
} }
fun PsiMethod.getJavaMethodDescriptor(): FunctionDescriptor? { fun PsiMethod.getJavaMethodDescriptor(): FunctionDescriptor? {
val method = getOriginalElement() as? PsiMethod ?: return null val method = getOriginalElement() as? PsiMethod ?: return null
val resolver = JavaResolveExtension.getResolver(method.getProject(), method) val resolver = method.getJavaDescriptorResolver()
return when { return when {
method.isConstructor() -> resolver.resolveConstructor(JavaConstructorImpl(method)) method.isConstructor() -> resolver.resolveConstructor(JavaConstructorImpl(method))
else -> resolver.resolveMethod(JavaMethodImpl(method)) else -> resolver.resolveMethod(JavaMethodImpl(method))
@@ -58,11 +41,11 @@ fun PsiMethod.getJavaMethodDescriptor(): FunctionDescriptor? {
} }
fun PsiClass.getJavaClassDescriptor(): ClassDescriptor? { fun PsiClass.getJavaClassDescriptor(): ClassDescriptor? {
return JavaResolveExtension.getResolver(getProject(), this).resolveClass(JavaClassImpl(this)) return getJavaDescriptorResolver().resolveClass(JavaClassImpl(this))
} }
fun PsiField.getJavaFieldDescriptor(): PropertyDescriptor? { fun PsiField.getJavaFieldDescriptor(): PropertyDescriptor? {
return JavaResolveExtension.getResolver(getProject(), this).resolveField(JavaFieldImpl(this)) return getJavaDescriptorResolver().resolveField(JavaFieldImpl(this))
} }
fun PsiMember.getJavaMemberDescriptor(): DeclarationDescriptor? { fun PsiMember.getJavaMemberDescriptor(): DeclarationDescriptor? {
@@ -24,21 +24,17 @@ import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.containers.SLRUCache import com.intellij.util.containers.SLRUCache
import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.analyzer.EmptyResolverForProject
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.idea.project.AnalyzerFacadeProvider import org.jetbrains.kotlin.idea.project.AnalyzerFacadeProvider
import org.jetbrains.kotlin.idea.project.ResolveElementCache
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.js.resolve.JsPlatform import org.jetbrains.kotlin.js.resolve.JsPlatform
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.JetCodeFragment
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.lazy.ResolveSession import org.jetbrains.kotlin.resolve.lazy.ResolveSession
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.utils.keysToMap import org.jetbrains.kotlin.utils.keysToMap
import kotlin.platform.platformStatic import kotlin.platform.platformStatic
@@ -50,37 +46,43 @@ public class KotlinCacheService(val project: Project) {
} }
public fun getResolutionFacade(elements: List<JetElement>): ResolutionFacade { public fun getResolutionFacade(elements: List<JetElement>): ResolutionFacade {
return ResolutionFacadeImpl( return getFacadeToAnalyzeFiles(elements.map { it.getContainingJetFile() })
project,
getCacheToAnalyzeFiles(elements.map { it.getContainingJetFile() })
)
} }
private val globalCachesPerPlatform = listOf(JvmPlatform, JsPlatform).keysToMap { platform -> GlobalCache(platform) } private val globalFacadesPerPlatform = listOf(JvmPlatform, JsPlatform).keysToMap { platform -> GlobalFacade(platform) }
private inner class GlobalCache(platform: TargetPlatform) { private inner class GlobalFacade(platform: TargetPlatform) {
val librariesCache = KotlinResolveCache(project) { val facadeForLibraries = ResolutionFacadeImpl(project) {
globalResolveSessionProvider( globalResolveSessionProvider(
project, platform, project,
platform,
logProcessCanceled = true, logProcessCanceled = true,
moduleFilter = { it.isLibraryClasses() }, moduleFilter = { it.isLibraryClasses() },
dependencies = listOf( dependencies = listOf(
LibraryModificationTracker.getInstance(project), LibraryModificationTracker.getInstance(project),
ProjectRootModificationTracker.getInstance(project))) ProjectRootModificationTracker.getInstance(project)
)
)
} }
val modulesCache = KotlinResolveCache(project) { val facadeForModules = ResolutionFacadeImpl(project) {
globalResolveSessionProvider(project, platform, globalResolveSessionProvider(
reuseDataFromCache = librariesCache, project,
moduleFilter = { !it.isLibraryClasses() }, platform,
dependencies = listOf(PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT)) reuseDataFrom = facadeForLibraries,
moduleFilter = { !it.isLibraryClasses() },
dependencies = listOf(PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT))
} }
} }
private fun getGlobalCache(platform: TargetPlatform) = globalCachesPerPlatform[platform]!!.modulesCache deprecated("Use JetElement.getResolutionFacade(), please avoid introducing new usages")
private fun getGlobalLibrariesCache(platform: TargetPlatform) = globalCachesPerPlatform[platform]!!.librariesCache public fun getGlobalFacade(platform: TargetPlatform): ResolutionFacade = globalFacade(platform)
private fun createCacheForSyntheticFiles(files: Set<JetFile>): KotlinResolveCache { private fun globalFacade(platform: TargetPlatform) = globalFacadesPerPlatform[platform]!!.facadeForModules
private fun librariesFacade(platform: TargetPlatform) = globalFacadesPerPlatform[platform]!!.facadeForLibraries
private fun createFacadeForSyntheticFiles(files: Set<JetFile>): ResolutionFacadeImpl {
// we assume that all files come from the same module // we assume that all files come from the same module
val targetPlatform = files.map { TargetPlatformDetector.getPlatform(it) }.toSet().single() val targetPlatform = files.map { TargetPlatformDetector.getPlatform(it) }.toSet().single()
val syntheticFileModule = files.map { it.getModuleInfo() }.toSet().single() val syntheticFileModule = files.map { it.getModuleInfo() }.toSet().single()
@@ -91,11 +93,12 @@ public class KotlinCacheService(val project: Project) {
return when { return when {
syntheticFileModule is ModuleSourceInfo -> { syntheticFileModule is ModuleSourceInfo -> {
val dependentModules = syntheticFileModule.getDependentModules() val dependentModules = syntheticFileModule.getDependentModules()
KotlinResolveCache(project) { ResolutionFacadeImpl(project) {
globalResolveSessionProvider( globalResolveSessionProvider(
project, targetPlatform, project,
targetPlatform,
syntheticFiles = files, syntheticFiles = files,
reuseDataFromCache = getGlobalCache(targetPlatform), reuseDataFrom = globalFacade(targetPlatform),
moduleFilter = { it in dependentModules }, moduleFilter = { it in dependentModules },
dependencies = dependenciesForSyntheticFileCache dependencies = dependenciesForSyntheticFileCache
) )
@@ -103,11 +106,12 @@ public class KotlinCacheService(val project: Project) {
} }
syntheticFileModule is LibrarySourceInfo || syntheticFileModule is NotUnderContentRootModuleInfo -> { syntheticFileModule is LibrarySourceInfo || syntheticFileModule is NotUnderContentRootModuleInfo -> {
KotlinResolveCache(project) { ResolutionFacadeImpl(project) {
globalResolveSessionProvider( globalResolveSessionProvider(
project, targetPlatform, project,
targetPlatform,
syntheticFiles = files, syntheticFiles = files,
reuseDataFromCache = getGlobalLibrariesCache(targetPlatform), reuseDataFrom = librariesFacade(targetPlatform),
moduleFilter = { it == syntheticFileModule }, moduleFilter = { it == syntheticFileModule },
dependencies = dependenciesForSyntheticFileCache dependencies = dependenciesForSyntheticFileCache
) )
@@ -119,9 +123,10 @@ public class KotlinCacheService(val project: Project) {
// currently the only known scenario is when we cannot determine that file is a library source // currently the only known scenario is when we cannot determine that file is a library source
// (file under both classes and sources root) // (file under both classes and sources root)
LOG.warn("Creating cache with synthetic files ($files) in classes of library $syntheticFileModule") LOG.warn("Creating cache with synthetic files ($files) in classes of library $syntheticFileModule")
KotlinResolveCache(project) { ResolutionFacadeImpl(project) {
globalResolveSessionProvider( globalResolveSessionProvider(
project, targetPlatform, project,
targetPlatform,
syntheticFiles = files, syntheticFiles = files,
moduleFilter = { true }, moduleFilter = { true },
dependencies = dependenciesForSyntheticFileCache dependencies = dependenciesForSyntheticFileCache
@@ -136,14 +141,14 @@ public class KotlinCacheService(val project: Project) {
private val syntheticFileCachesLock = Any() private val syntheticFileCachesLock = Any()
private val slruCacheProvider = CachedValueProvider { private val slruCacheProvider = CachedValueProvider {
CachedValueProvider.Result(object : SLRUCache<Set<JetFile>, KotlinResolveCache>(2, 3) { CachedValueProvider.Result(object : SLRUCache<Set<JetFile>, ResolutionFacadeImpl>(2, 3) {
override fun createValue(files: Set<JetFile>): KotlinResolveCache { override fun createValue(files: Set<JetFile>): ResolutionFacadeImpl {
return createCacheForSyntheticFiles(files) return createFacadeForSyntheticFiles(files)
} }
}, LibraryModificationTracker.getInstance(project), ProjectRootModificationTracker.getInstance(project)) }, LibraryModificationTracker.getInstance(project), ProjectRootModificationTracker.getInstance(project))
} }
private fun getCacheForSyntheticFiles(files: Set<JetFile>): KotlinResolveCache { private fun getFacadeForSyntheticFiles(files: Set<JetFile>): ResolutionFacadeImpl {
return synchronized(syntheticFileCachesLock) { return synchronized(syntheticFileCachesLock) {
//NOTE: computations inside createCacheForSyntheticFiles depend on project root structure //NOTE: computations inside createCacheForSyntheticFiles depend on project root structure
// so we additionally drop the whole slru cache on change // so we additionally drop the whole slru cache on change
@@ -153,13 +158,13 @@ public class KotlinCacheService(val project: Project) {
public fun getLazyResolveSession(element: JetElement): ResolveSession { public fun getLazyResolveSession(element: JetElement): ResolveSession {
val file = element.getContainingJetFile() val file = element.getContainingJetFile()
return getCacheToAnalyzeFiles(listOf(file)).getLazyResolveSession(file) return getFacadeToAnalyzeFiles(listOf(file)).getLazyResolveSession(file)
} }
private fun getCacheToAnalyzeFiles(files: Collection<JetFile>): KotlinResolveCache { private fun getFacadeToAnalyzeFiles(files: Collection<JetFile>): ResolutionFacadeImpl {
val syntheticFiles = findSyntheticFiles(files) val syntheticFiles = findSyntheticFiles(files)
return if (syntheticFiles.isNotEmpty()) { return if (syntheticFiles.isNotEmpty()) {
getCacheForSyntheticFiles(syntheticFiles) getFacadeForSyntheticFiles(syntheticFiles)
} }
else { else {
val firstFile = files.firstOrNull() val firstFile = files.firstOrNull()
@@ -167,7 +172,7 @@ public class KotlinCacheService(val project: Project) {
TargetPlatformDetector.getPlatform(firstFile) TargetPlatformDetector.getPlatform(firstFile)
else else
TargetPlatformDetector.getDefaultPlatform() TargetPlatformDetector.getDefaultPlatform()
getGlobalCache(targetPlatform) globalFacade(targetPlatform)
} }
} }
@@ -183,10 +188,6 @@ public class KotlinCacheService(val project: Project) {
?: throw AssertionError("Analyzing kotlin code fragment of type $javaClass with java context of type ${contextElement.javaClass}") ?: throw AssertionError("Analyzing kotlin code fragment of type $javaClass with java context of type ${contextElement.javaClass}")
return if (contextFile is JetCodeFragment) contextFile.getContextFile() else contextFile return if (contextFile is JetCodeFragment) contextFile.getContextFile() else contextFile
} }
public fun <T> get(extension: CacheExtension<T>): T {
return getGlobalCache(extension.platform)[extension]
}
} }
private fun globalResolveSessionProvider( private fun globalResolveSessionProvider(
@@ -194,23 +195,21 @@ private fun globalResolveSessionProvider(
platform: TargetPlatform, platform: TargetPlatform,
dependencies: Collection<Any>, dependencies: Collection<Any>,
moduleFilter: (IdeaModuleInfo) -> Boolean, moduleFilter: (IdeaModuleInfo) -> Boolean,
reuseDataFromCache: KotlinResolveCache? = null, reuseDataFrom: ResolutionFacadeImpl? = null,
syntheticFiles: Collection<JetFile> = listOf(), syntheticFiles: Collection<JetFile> = listOf(),
logProcessCanceled: Boolean = false logProcessCanceled: Boolean = false
): CachedValueProvider.Result<ModuleResolverProvider> { ): CachedValueProvider.Result<ModuleResolverProvider> {
val analyzerFacade = AnalyzerFacadeProvider.getAnalyzerFacade(platform) val delegateResolverProvider = reuseDataFrom?.moduleResolverProvider
val delegateResolverProvider = reuseDataFromCache?.moduleResolverProvider ?: EmptyModuleResolverProvider val delegateResolverForProject = delegateResolverProvider?.resolverForProject ?: EmptyResolverForProject()
val globalContext = (delegateResolverProvider as? ModuleResolverProviderImpl) val globalContext = (delegateResolverProvider as? ModuleResolverProviderImpl)?.globalContext
?.globalContext
?.withCompositeExceptionTrackerUnderSameLock() ?.withCompositeExceptionTrackerUnderSameLock()
?: GlobalContext(logProcessCanceled) ?: GlobalContext(logProcessCanceled)
val moduleResolverProvider = createModuleResolverProvider( val moduleResolverProvider = createModuleResolverProvider(
project, globalContext, analyzerFacade, syntheticFiles, delegateResolverProvider, moduleFilter project, globalContext,
AnalyzerFacadeProvider.getAnalyzerFacade(platform),
syntheticFiles, delegateResolverForProject, moduleFilter
) )
val allDependencies = dependencies + listOf(moduleResolverProvider.exceptionTracker) val allDependencies = dependencies + listOf(moduleResolverProvider.exceptionTracker)
return CachedValueProvider.Result.create(moduleResolverProvider, allDependencies) return CachedValueProvider.Result.create(moduleResolverProvider, allDependencies)
} }
@@ -49,79 +49,6 @@ public interface CacheExtension<T> {
public fun getData(resolverProvider: ModuleResolverProvider): T public fun getData(resolverProvider: ModuleResolverProvider): T
} }
private class KotlinResolveCache(
val project: Project,
computeModuleResolverProvider: () -> CachedValueProvider.Result<ModuleResolverProvider>
) {
private val resolverCache = SynchronizedCachedValue(project, computeModuleResolverProvider, trackValue = false)
val moduleResolverProvider: ModuleResolverProvider
get() = resolverCache.getValue()
public fun getLazyResolveSession(element: JetElement): ResolveSession {
return moduleResolverProvider.resolverByModule(element.getModuleInfo()).componentProvider.get<ResolveSession>()
}
public fun <T> getService(element: JetElement, serviceClass: Class<T>): T {
//TODO_R:
return moduleResolverProvider.resolverForProject.resolverForModule(element.getModuleInfo()).componentProvider.resolve(serviceClass)?.getValue() as T
}
public fun <T> getService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T {
//TODO_R:
return moduleResolverProvider.resolverForProject.resolverForModuleDescriptor(moduleDescriptor).componentProvider.resolve(serviceClass)?.getValue() as T
}
public fun <T> getIdeService(element: JetElement, serviceClass: Class<T>): T {
//TODO_R:
return moduleResolverProvider.resolverForProject.resolverForModule(element.getModuleInfo()).componentProvider.create(serviceClass)
}
public fun <T> getIdeService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T {
//TODO_R:
return moduleResolverProvider.resolverForProject.resolverForModuleDescriptor(moduleDescriptor).componentProvider.create(serviceClass)
}
public fun getLazyResolveSession(moduleDescriptor: ModuleDescriptor): ResolveSession {
return moduleResolverProvider.resolveSessionForBodiesByDescriptor(moduleDescriptor)
}
public fun <T> get(extension: CacheExtension<T>): T {
return extension.getData(moduleResolverProvider)
}
private val analysisResults = CachedValuesManager.getManager(project).createCachedValue(
{
val resolverProvider = moduleResolverProvider
val results = object : SLRUCache<JetFile, PerFileAnalysisCache>(2, 3) {
override fun createValue(file: JetFile?): PerFileAnalysisCache {
return PerFileAnalysisCache(file!!, resolverProvider.resolverByModule(file.getModuleInfo()).componentProvider)
}
}
CachedValueProvider.Result(results, PsiModificationTracker.MODIFICATION_COUNT, resolverProvider.exceptionTracker)
}, false)
fun getAnalysisResultsForElements(elements: Collection<JetElement>): AnalysisResult {
assert(elements.isNotEmpty(), "elements collection should not be empty")
val slruCache = synchronized(analysisResults) {
analysisResults.getValue()!!
}
val results = elements.map {
val perFileCache = synchronized(slruCache) {
slruCache[it.getContainingJetFile()]
}
perFileCache.getAnalysisResults(it)
}
val withError = results.firstOrNull { it.isError() }
val bindingContext = CompositeBindingContext.create(results.map { it.bindingContext })
return if (withError != null)
AnalysisResult.error(bindingContext, withError.error)
else
//TODO: (module refactoring) several elements are passed here in debugger
AnalysisResult.success(bindingContext, getLazyResolveSession(elements.first()).getModuleDescriptor())
}
}
private class PerFileAnalysisCache(val file: JetFile, val componentProvider: ComponentProvider) { private class PerFileAnalysisCache(val file: JetFile, val componentProvider: ComponentProvider) {
private val cache = HashMap<PsiElement, AnalysisResult>() private val cache = HashMap<PsiElement, AnalysisResult>()
@@ -21,17 +21,16 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.JdkOrderEntry import com.intellij.openapi.roots.JdkOrderEntry
import com.intellij.openapi.roots.LibraryOrderEntry import com.intellij.openapi.roots.LibraryOrderEntry
import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.ModuleRootManager
import org.jetbrains.kotlin.analyzer.* import org.jetbrains.kotlin.analyzer.AnalyzerFacade
import org.jetbrains.kotlin.container.get import org.jetbrains.kotlin.analyzer.ModuleContent
import org.jetbrains.kotlin.analyzer.ResolverForProject
import org.jetbrains.kotlin.context.GlobalContextImpl import org.jetbrains.kotlin.context.GlobalContextImpl
import org.jetbrains.kotlin.context.withProject import org.jetbrains.kotlin.context.withProject
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.idea.project.IdeaEnvironment import org.jetbrains.kotlin.idea.project.IdeaEnvironment
import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
import org.jetbrains.kotlin.storage.ExceptionTracker import org.jetbrains.kotlin.storage.ExceptionTracker
fun createModuleResolverProvider( fun createModuleResolverProvider(
@@ -39,7 +38,7 @@ fun createModuleResolverProvider(
globalContext: GlobalContextImpl, globalContext: GlobalContextImpl,
analyzerFacade: AnalyzerFacade<JvmPlatformParameters>, analyzerFacade: AnalyzerFacade<JvmPlatformParameters>,
syntheticFiles: Collection<JetFile>, syntheticFiles: Collection<JetFile>,
delegateProvider: ModuleResolverProvider, delegateResolver: ResolverForProject<IdeaModuleInfo>,
moduleFilter: (IdeaModuleInfo) -> Boolean moduleFilter: (IdeaModuleInfo) -> Boolean
): ModuleResolverProvider { ): ModuleResolverProvider {
@@ -64,7 +63,7 @@ fun createModuleResolverProvider(
val resolverForProject = analyzerFacade.setupResolverForProject( val resolverForProject = analyzerFacade.setupResolverForProject(
globalContext.withProject(project), modulesToCreateResolversFor, modulesContent, globalContext.withProject(project), modulesToCreateResolversFor, modulesContent,
jvmPlatformParameters, IdeaEnvironment, delegateProvider.resolverForProject jvmPlatformParameters, IdeaEnvironment, delegateResolver
) )
return resolverForProject return resolverForProject
} }
@@ -73,8 +72,7 @@ fun createModuleResolverProvider(
return ModuleResolverProviderImpl( return ModuleResolverProviderImpl(
resolverForProject, resolverForProject,
globalContext, globalContext
delegateProvider
) )
} }
@@ -105,36 +103,12 @@ private fun collectAllModuleInfosFromIdeaModel(project: Project): List<IdeaModul
interface ModuleResolverProvider { interface ModuleResolverProvider {
val exceptionTracker: ExceptionTracker val exceptionTracker: ExceptionTracker
fun resolverByModule(module: IdeaModuleInfo): ResolverForModule = resolverForProject.resolverForModule(module)
fun resolveSessionForBodiesByModule(module: IdeaModuleInfo): ResolveSession {
return resolveSessionForBodiesByDescriptor(resolverForProject.descriptorForModule(module))
}
fun resolveSessionForBodiesByDescriptor(descriptor: ModuleDescriptor): ResolveSession
val resolverForProject: ResolverForProject<IdeaModuleInfo> val resolverForProject: ResolverForProject<IdeaModuleInfo>
} }
object EmptyModuleResolverProvider: ModuleResolverProvider {
override val exceptionTracker: ExceptionTracker
get() = throw IllegalStateException("Should not be called")
override val resolverForProject: ResolverForProject<IdeaModuleInfo> = EmptyResolverForProject()
override fun resolveSessionForBodiesByDescriptor(descriptor: ModuleDescriptor): ResolveSession {
throw IllegalStateException("Trying to obtain resolve session for $descriptor not present in this resolver")
}
}
class ModuleResolverProviderImpl( class ModuleResolverProviderImpl(
override val resolverForProject: ResolverForProject<IdeaModuleInfo>, override val resolverForProject: ResolverForProject<IdeaModuleInfo>,
val globalContext: GlobalContextImpl, val globalContext: GlobalContextImpl
val delegateProvider: ModuleResolverProvider = EmptyModuleResolverProvider ) : ModuleResolverProvider {
): ModuleResolverProvider {
override val exceptionTracker: ExceptionTracker = globalContext.exceptionTracker override val exceptionTracker: ExceptionTracker = globalContext.exceptionTracker
override fun resolveSessionForBodiesByDescriptor(descriptor: ModuleDescriptor): ResolveSession {
return resolverForProject.resolverForModuleDescriptor(descriptor).componentProvider.get<ResolveSession>()
}
} }
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.idea.caches.resolve package org.jetbrains.kotlin.idea.caches.resolve
import com.intellij.psi.PsiElement
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
@@ -44,11 +45,11 @@ public interface ResolutionFacade {
public fun <T> get(extension: CacheExtension<T>): T public fun <T> get(extension: CacheExtension<T>): T
public fun <T> getFrontendService(element: JetElement, serviceClass: Class<T>): T public fun <T> getFrontendService(element: PsiElement, serviceClass: Class<T>): T
public fun <T> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T public fun <T> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T
public fun <T> getIdeService(element: JetElement, serviceClass: Class<T>): T public fun <T> getIdeService(element: PsiElement, serviceClass: Class<T>): T
public fun <T> getIdeService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T public fun <T> getIdeService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T
@@ -65,13 +66,13 @@ public interface ResolutionFacade {
} }
} }
public inline fun <reified T> ResolutionFacade.getService(element: JetElement): T public inline fun <reified T> ResolutionFacade.frontendService(element: PsiElement): T
= this.getFrontendService(element, javaClass<T>()) = this.getFrontendService(element, javaClass<T>())
public inline fun <reified T> ResolutionFacade.getService(moduleDescriptor: ModuleDescriptor): T public inline fun <reified T> ResolutionFacade.frontendService(moduleDescriptor: ModuleDescriptor): T
= this.getFrontendService(moduleDescriptor, javaClass<T>()) = this.getFrontendService(moduleDescriptor, javaClass<T>())
public inline fun <reified T> ResolutionFacade.ideService(element: JetElement): T public inline fun <reified T> ResolutionFacade.ideService(element: PsiElement): T
= this.getIdeService(element, javaClass<T>()) = this.getIdeService(element, javaClass<T>())
public inline fun <reified T> ResolutionFacade.ideService(moduleDescriptor: ModuleDescriptor): T public inline fun <reified T> ResolutionFacade.ideService(moduleDescriptor: ModuleDescriptor): T
@@ -17,7 +17,14 @@
package org.jetbrains.kotlin.idea.caches.resolve package org.jetbrains.kotlin.idea.caches.resolve
import com.intellij.openapi.project.Project 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.AnalysisResult
import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.container.getService
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.idea.project.ResolveElementCache import org.jetbrains.kotlin.idea.project.ResolveElementCache
@@ -26,59 +33,101 @@ import org.jetbrains.kotlin.psi.JetDeclaration
import org.jetbrains.kotlin.psi.JetElement import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.psi.JetPsiFactory import org.jetbrains.kotlin.psi.JetPsiFactory
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.BindingTraceContext
import org.jetbrains.kotlin.resolve.ImportPath
import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.resolve.scopes.JetScope
private class ResolutionFacadeImpl(private val project: Project, private val cache: KotlinResolveCache) : ResolutionFacade { private class ResolutionFacadeImpl(
override fun <T> getIdeService(element: JetElement, serviceClass: Class<T>): T { private val project: Project,
return cache.getIdeService(element, serviceClass) computeModuleResolverProvider: () -> CachedValueProvider.Result<ModuleResolverProvider>
) : ResolutionFacade {
override fun <T> get(extension: CacheExtension<T>): T = error("TODO: support")
private val resolverCache = SynchronizedCachedValue(project, computeModuleResolverProvider, trackValue = false)
val moduleResolverProvider: ModuleResolverProvider
get() = resolverCache.getValue()
public fun getLazyResolveSession(element: JetElement): ResolveSession {
return resolverForModuleInfo(element.getModuleInfo()).componentProvider.get<ResolveSession>()
}
private fun resolverForModuleInfo(moduleInfo: IdeaModuleInfo) = moduleResolverProvider.resolverForProject.resolverForModule(moduleInfo)
private fun resolverForDescriptor(moduleDescriptor: ModuleDescriptor) = moduleResolverProvider.resolverForProject.resolverForModuleDescriptor(moduleDescriptor)
override fun <T> getFrontendService(element: PsiElement, serviceClass: Class<T>): T {
return resolverForModuleInfo(element.getModuleInfo()).componentProvider.getService(serviceClass)
}
override fun <T> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T {
return resolverForDescriptor(moduleDescriptor).componentProvider.getService(serviceClass)
}
override fun <T> getIdeService(element: PsiElement, serviceClass: Class<T>): T {
return resolverForModuleInfo(element.getModuleInfo()).componentProvider.create(serviceClass)
} }
override fun <T> getIdeService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T { override fun <T> getIdeService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T {
return cache.getIdeService(moduleDescriptor, serviceClass) return resolverForDescriptor(moduleDescriptor).componentProvider.create(serviceClass)
} }
override fun analyze(element: JetElement, bodyResolveMode: BodyResolveMode): BindingContext { override fun analyze(element: JetElement, bodyResolveMode: BodyResolveMode): BindingContext {
val resolveElementCache = cache.getService(element, javaClass<ResolveElementCache>()) val resolveElementCache = getFrontendService(element, javaClass<ResolveElementCache>())
return resolveElementCache.resolveToElement(element, bodyResolveMode) return resolveElementCache.resolveToElement(element, bodyResolveMode)
} }
override fun findModuleDescriptor(element: JetElement): ModuleDescriptor { override fun findModuleDescriptor(element: JetElement): ModuleDescriptor {
return cache.getLazyResolveSession(element).getModuleDescriptor() return moduleResolverProvider.resolverForProject.descriptorForModule(element.getModuleInfo())
} }
override fun resolveToDescriptor(declaration: JetDeclaration): DeclarationDescriptor { override fun resolveToDescriptor(declaration: JetDeclaration): DeclarationDescriptor {
return cache.getLazyResolveSession(declaration).resolveToDescriptor(declaration) return getLazyResolveSession(declaration).resolveToDescriptor(declaration)
} }
override fun analyzeFullyAndGetResult(elements: Collection<JetElement>): AnalysisResult { override fun analyzeFullyAndGetResult(elements: Collection<JetElement>): AnalysisResult {
return cache.getAnalysisResultsForElements(elements) return getAnalysisResultsForElements(elements)
} }
override fun getFileTopLevelScope(file: JetFile): JetScope { override fun getFileTopLevelScope(file: JetFile): JetScope {
return cache.getLazyResolveSession(file).getFileScopeProvider().getFileScope(file) return getLazyResolveSession(file).getFileScopeProvider().getFileScope(file)
}
override fun <T> getFrontendService(element: JetElement, serviceClass: Class<T>): T {
return cache.getService(element, serviceClass)
}
override fun <T> getFrontendService(moduleDescriptor: ModuleDescriptor, serviceClass: Class<T>): T {
return cache.getService(moduleDescriptor, serviceClass)
} }
override fun resolveImportReference(moduleDescriptor: ModuleDescriptor, fqName: FqName): Collection<DeclarationDescriptor> { override fun resolveImportReference(moduleDescriptor: ModuleDescriptor, fqName: FqName): Collection<DeclarationDescriptor> {
val importDirective = JetPsiFactory(project).createImportDirective(ImportPath(fqName, false)) val importDirective = JetPsiFactory(project).createImportDirective(ImportPath(fqName, false))
val qualifiedExpressionResolver = this.getService<QualifiedExpressionResolver>(moduleDescriptor) val qualifiedExpressionResolver = this.frontendService<QualifiedExpressionResolver>(moduleDescriptor)
return qualifiedExpressionResolver.processImportReference( return qualifiedExpressionResolver.processImportReference(
importDirective, moduleDescriptor, BindingTraceContext(), QualifiedExpressionResolver.LookupMode.EVERYTHING).getAllDescriptors() importDirective, moduleDescriptor, BindingTraceContext(), QualifiedExpressionResolver.LookupMode.EVERYTHING).getAllDescriptors()
} }
override fun <T> get(extension: CacheExtension<T>): T { private val analysisResults = CachedValuesManager.getManager(project).createCachedValue(
return cache[extension] {
val resolverProvider = moduleResolverProvider
val results = object : SLRUCache<JetFile, PerFileAnalysisCache>(2, 3) {
override fun createValue(file: JetFile?): PerFileAnalysisCache {
return PerFileAnalysisCache(file!!, resolverProvider.resolverForProject.resolverForModule(file.getModuleInfo()).componentProvider)
}
}
CachedValueProvider.Result(results, PsiModificationTracker.MODIFICATION_COUNT, resolverProvider.exceptionTracker)
}, false)
fun getAnalysisResultsForElements(elements: Collection<JetElement>): AnalysisResult {
assert(elements.isNotEmpty(), "elements collection should not be empty")
val slruCache = synchronized(analysisResults) {
analysisResults.getValue()!!
}
val results = elements.map {
val perFileCache = synchronized(slruCache) {
slruCache[it.getContainingJetFile()]
}
perFileCache.getAnalysisResults(it)
}
val withError = results.firstOrNull { it.isError() }
val bindingContext = CompositeBindingContext.create(results.map { it.bindingContext })
return if (withError != null)
AnalysisResult.error(bindingContext, withError.error)
else
//TODO: (module refactoring) several elements are passed here in debugger
AnalysisResult.success(bindingContext, getLazyResolveSession(elements.first()).getModuleDescriptor())
} }
} }
@@ -28,8 +28,8 @@ import com.intellij.psi.search.DelegatingGlobalSearchScope
import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.frontendService
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.getService
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper
import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper
@@ -46,8 +46,8 @@ import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.psi.psiUtil.prevLeaf import org.jetbrains.kotlin.psi.psiUtil.prevLeaf
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
@@ -147,7 +147,7 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
var receiverTypes = receiversData.receivers.flatMap { receiverValue -> var receiverTypes = receiversData.receivers.flatMap { receiverValue ->
val dataFlowValue = DataFlowValueFactory.createDataFlowValue(receiverValue, bindingContext, moduleDescriptor) val dataFlowValue = DataFlowValueFactory.createDataFlowValue(receiverValue, bindingContext, moduleDescriptor)
if (dataFlowValue.isPredictable) { // we don't include smart cast receiver types for "unpredictable" receiver value to mark members grayed if (dataFlowValue.isPredictable) { // we don't include smart cast receiver types for "unpredictable" receiver value to mark members grayed
resolutionFacade.getService<SmartCastManager>(file) resolutionFacade.frontendService<SmartCastManager>(file)
.getSmartCastVariantsWithLessSpecificExcluded(receiverValue, bindingContext, moduleDescriptor, dataFlowInfo) .getSmartCastVariantsWithLessSpecificExcluded(receiverValue, bindingContext, moduleDescriptor, dataFlowInfo)
} }
else { else {
@@ -20,11 +20,11 @@ import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.getService import org.jetbrains.kotlin.idea.caches.resolve.frontendService
import org.jetbrains.kotlin.idea.caches.resolve.ideService
import org.jetbrains.kotlin.idea.completion.smart.TypesWithContainsDetector import org.jetbrains.kotlin.idea.completion.smart.TypesWithContainsDetector
import org.jetbrains.kotlin.idea.core.IterableTypesDetection import org.jetbrains.kotlin.idea.core.IterableTypesDetection
import org.jetbrains.kotlin.idea.core.IterableTypesDetector import org.jetbrains.kotlin.idea.core.IterableTypesDetector
import org.jetbrains.kotlin.idea.caches.resolve.ideService
import org.jetbrains.kotlin.idea.core.mapArgumentsToParameters import org.jetbrains.kotlin.idea.core.mapArgumentsToParameters
import org.jetbrains.kotlin.idea.util.FuzzyType import org.jetbrains.kotlin.idea.util.FuzzyType
import org.jetbrains.kotlin.idea.util.fuzzyReturnType import org.jetbrains.kotlin.idea.util.fuzzyReturnType
@@ -247,7 +247,7 @@ class ExpectedInfos(
ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS, ContextDependency.INDEPENDENT, CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS,
CallChecker.DoNothing, false) CallChecker.DoNothing, false)
val callResolutionContext = context.replaceCollectAllCandidates(true) val callResolutionContext = context.replaceCollectAllCandidates(true)
val callResolver = resolutionFacade.getService<CallResolver>(moduleDescriptor) val callResolver = resolutionFacade.frontendService<CallResolver>(moduleDescriptor)
val results: OverloadResolutionResults<FunctionDescriptor> = callResolver.resolveFunctionCall(callResolutionContext) val results: OverloadResolutionResults<FunctionDescriptor> = callResolver.resolveFunctionCall(callResolutionContext)
val expectedInfos = LinkedHashSet<ExpectedInfo>() val expectedInfos = LinkedHashSet<ExpectedInfo>()
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.impl.SubpackagesScope import org.jetbrains.kotlin.descriptors.impl.SubpackagesScope
import org.jetbrains.kotlin.frontend.di.createContainerForMacros import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.JetPsiFactory import org.jetbrains.kotlin.psi.JetPsiFactory
@@ -31,8 +31,10 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.TypeResolver import org.jetbrains.kotlin.resolve.TypeResolver
import org.jetbrains.kotlin.resolve.scopes.ChainedScope import org.jetbrains.kotlin.resolve.scopes.ChainedScope
import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.types.IndexedParametersSubstitution
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.types.SubstitutionUtils
import org.jetbrains.kotlin.types.Variance
import java.util.HashMap import java.util.HashMap
public class HeuristicSignatures( public class HeuristicSignatures(
@@ -24,7 +24,7 @@ import com.intellij.psi.stubs.StringStubIndexExtension
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.getService import org.jetbrains.kotlin.idea.caches.resolve.frontendService
import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper
import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.stubindex.* import org.jetbrains.kotlin.idea.stubindex.*
@@ -115,7 +115,7 @@ public class KotlinIndicesHelper(
private fun possibleReceiverTypeNames(receiverValues: Collection<ReceiverValue>, dataFlowInfo: DataFlowInfo, bindingContext: BindingContext): Set<String> { private fun possibleReceiverTypeNames(receiverValues: Collection<ReceiverValue>, dataFlowInfo: DataFlowInfo, bindingContext: BindingContext): Set<String> {
val result = HashSet<String>() val result = HashSet<String>()
for (receiverValue in receiverValues) { for (receiverValue in receiverValues) {
val smartCastManager = resolutionFacade.getService<SmartCastManager>(moduleDescriptor) val smartCastManager = resolutionFacade.frontendService<SmartCastManager>(moduleDescriptor)
for (type in smartCastManager.getSmartCastVariants(receiverValue, bindingContext, moduleDescriptor, dataFlowInfo)) { for (type in smartCastManager.getSmartCastVariants(receiverValue, bindingContext, moduleDescriptor, dataFlowInfo)) {
result.addTypeNames(type) result.addTypeNames(type)
} }
@@ -16,25 +16,26 @@
package org.jetbrains.kotlin.idea.core package org.jetbrains.kotlin.idea.core
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
import com.intellij.psi.PsiClass import com.intellij.psi.PsiClass
import org.jetbrains.kotlin.psi.JetClassOrObject
import org.jetbrains.kotlin.asJava.KotlinLightClass import org.jetbrains.kotlin.asJava.KotlinLightClass
import org.jetbrains.kotlin.idea.caches.resolve.KotlinLightClassForDecompiledDeclaration
import org.jetbrains.kotlin.idea.caches.resolve.JavaResolveExtension
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.KotlinLightClassForDecompiledDeclaration
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.frontendService
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
import org.jetbrains.kotlin.psi.JetClassOrObject
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
public fun ResolutionFacade.psiClassToDescriptor( public fun ResolutionFacade.psiClassToDescriptor(
psiClass: PsiClass, psiClass: PsiClass,
declarationTranslator: (JetClassOrObject) -> JetClassOrObject? = { it } declarationTranslator: (JetClassOrObject) -> JetClassOrObject? = { it }
): ClassifierDescriptor? { ): ClassifierDescriptor? {
return if (psiClass is KotlinLightClass && psiClass !is KotlinLightClassForDecompiledDeclaration) { return if (psiClass is KotlinLightClass && psiClass !is KotlinLightClassForDecompiledDeclaration) {
val origin = psiClass.getOrigin ()?: return null val origin = psiClass.getOrigin () ?: return null
val declaration = declarationTranslator(origin) ?: return null val declaration = declarationTranslator(origin) ?: return null
resolveToDescriptor(declaration) resolveToDescriptor(declaration)
} else { }
get(JavaResolveExtension)(psiClass).first.resolveClass(JavaClassImpl(psiClass)) else {
frontendService<JavaDescriptorResolver>(psiClass).resolveClass(JavaClassImpl(psiClass))
} as? ClassifierDescriptor } as? ClassifierDescriptor
} }
@@ -57,8 +57,8 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Severity import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
import org.jetbrains.kotlin.idea.JetLanguage import org.jetbrains.kotlin.idea.JetLanguage
import org.jetbrains.kotlin.idea.caches.resolve.JavaResolveExtension
import org.jetbrains.kotlin.idea.caches.resolve.KotlinCacheService import org.jetbrains.kotlin.idea.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.idea.caches.resolve.getJavaClassDescriptor
import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinEvaluateExpressionCache.CompiledDataDescriptor import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinEvaluateExpressionCache.CompiledDataDescriptor
import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinEvaluateExpressionCache.ParametersDescriptor import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinEvaluateExpressionCache.ParametersDescriptor
import org.jetbrains.kotlin.idea.debugger.evaluate.compilingEvaluator.loadClasses import org.jetbrains.kotlin.idea.debugger.evaluate.compilingEvaluator.loadClasses
@@ -67,7 +67,6 @@ import org.jetbrains.kotlin.idea.util.DebuggerUtils
import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.idea.util.attachment.attachmentByPsiFile import org.jetbrains.kotlin.idea.util.attachment.attachmentByPsiFile
import org.jetbrains.kotlin.idea.util.attachment.mergeAttachments import org.jetbrains.kotlin.idea.util.attachment.mergeAttachments
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
@@ -82,7 +81,8 @@ import org.jetbrains.kotlin.types.Flexibility
import org.jetbrains.org.objectweb.asm.* import org.jetbrains.org.objectweb.asm.*
import org.jetbrains.org.objectweb.asm.Opcodes.ASM5 import org.jetbrains.org.objectweb.asm.Opcodes.ASM5
import org.jetbrains.org.objectweb.asm.tree.MethodNode import org.jetbrains.org.objectweb.asm.tree.MethodNode
import java.util.* import java.util.Collections
import java.util.HashMap
private val RECEIVER_NAME = "\$receiver" private val RECEIVER_NAME = "\$receiver"
private val THIS_NAME = "this" private val THIS_NAME = "this"
@@ -540,8 +540,7 @@ fun Type.getClassDescriptor(project: Project): ClassDescriptor? {
val classes = JavaPsiFacade.getInstance(project).findClasses(jvmName.asString(), GlobalSearchScope.allScope(project)) val classes = JavaPsiFacade.getInstance(project).findClasses(jvmName.asString(), GlobalSearchScope.allScope(project))
if (classes.isEmpty()) null if (classes.isEmpty()) null
else { else {
val clazz = classes.first() classes.first().getJavaClassDescriptor()
JavaResolveExtension.getResolver(project, clazz).resolveClass(JavaClassImpl(clazz))
} }
} }
} }
@@ -18,11 +18,8 @@ package org.jetbrains.kotlin.idea.intentions
import com.intellij.codeInspection.ProblemHighlightType import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import org.jetbrains.kotlin.frontend.di.createContainerForMacros import org.jetbrains.kotlin.idea.caches.resolve.frontendService
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.getService
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
@@ -72,7 +69,7 @@ public class RemoveExplicitTypeArgumentsIntention : JetSelfTargetingOffsetIndepe
TypeUtils.NO_EXPECTED_TYPE TypeUtils.NO_EXPECTED_TYPE
} }
val dataFlow = context.getDataFlowInfo(callExpression) val dataFlow = context.getDataFlowInfo(callExpression)
val callResolver = resolutionFacade.getService<CallResolver>(callExpression) val callResolver = resolutionFacade.frontendService<CallResolver>(callExpression)
val resolutionResults = callResolver.resolveFunctionCall( val resolutionResults = callResolver.resolveFunctionCall(
BindingTraceContext(), scope, untypedCall, expectedType, dataFlow, false) BindingTraceContext(), scope, untypedCall, expectedType, dataFlow, false)
if (!resolutionResults.isSingleResult()) { if (!resolutionResults.isSingleResult()) {
@@ -40,7 +40,6 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.descriptors.VariableDescriptor; import org.jetbrains.kotlin.descriptors.VariableDescriptor;
import org.jetbrains.kotlin.idea.JetBundle; import org.jetbrains.kotlin.idea.JetBundle;
import org.jetbrains.kotlin.idea.JetIcons; import org.jetbrains.kotlin.idea.JetIcons;
import org.jetbrains.kotlin.idea.caches.resolve.JavaResolveExtension;
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage; import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers; import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers;
import org.jetbrains.kotlin.load.java.structure.impl.JavaConstructorImpl; import org.jetbrains.kotlin.load.java.structure.impl.JavaConstructorImpl;
@@ -160,7 +159,7 @@ public class KotlinSignatureAnnotationIntention extends BaseIntentionAction impl
private static String getDefaultSignature(@NotNull Project project, @NotNull PsiMember element) { private static String getDefaultSignature(@NotNull Project project, @NotNull PsiMember element) {
PsiMember analyzableAnnotationOwner = KotlinSignatureUtil.getAnalyzableAnnotationOwner(element); PsiMember analyzableAnnotationOwner = KotlinSignatureUtil.getAnalyzableAnnotationOwner(element);
assert analyzableAnnotationOwner != null; assert analyzableAnnotationOwner != null;
JavaDescriptorResolver javaDescriptorResolver = JavaResolveExtension.INSTANCE$.getResolver(project, analyzableAnnotationOwner); JavaDescriptorResolver javaDescriptorResolver = ResolvePackage.getJavaDescriptorResolver(analyzableAnnotationOwner);
if (analyzableAnnotationOwner instanceof PsiMethod) { if (analyzableAnnotationOwner instanceof PsiMethod) {
PsiMethod psiMethod = (PsiMethod) analyzableAnnotationOwner; PsiMethod psiMethod = (PsiMethod) analyzableAnnotationOwner;
@@ -39,15 +39,13 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.idea.JetIcons; import org.jetbrains.kotlin.idea.JetIcons;
import org.jetbrains.kotlin.idea.caches.resolve.JavaResolveExtension; import org.jetbrains.kotlin.idea.caches.resolve.KotlinCacheService;
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage; import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
import org.jetbrains.kotlin.idea.project.ProjectStructureUtil; import org.jetbrains.kotlin.idea.project.ProjectStructureUtil;
import org.jetbrains.kotlin.load.java.JavaBindingContext; import org.jetbrains.kotlin.load.java.JavaBindingContext;
import org.jetbrains.kotlin.load.java.structure.impl.JavaConstructorImpl;
import org.jetbrains.kotlin.load.java.structure.impl.JavaFieldImpl;
import org.jetbrains.kotlin.load.java.structure.impl.JavaMethodImpl;
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver; import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.Collection; import java.util.Collection;
@@ -114,18 +112,17 @@ public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider {
private static void markElement(@NotNull PsiElement element, @NotNull Collection<LineMarkerInfo> result) { private static void markElement(@NotNull PsiElement element, @NotNull Collection<LineMarkerInfo> result) {
Project project = element.getProject(); Project project = element.getProject();
PsiModifierListOwner annotationOwner = KotlinSignatureUtil.getAnalyzableAnnotationOwner(element); PsiModifierListOwner annotationOwner = KotlinSignatureUtil.getAnalyzableAnnotationOwner(element);
if (annotationOwner == null) { if (!(annotationOwner instanceof PsiMember)) {
return; return;
} }
JavaResolveExtension resolveExtension = JavaResolveExtension.INSTANCE$; DeclarationDescriptor memberDescriptor = ResolvePackage.getJavaMemberDescriptor((PsiMember) annotationOwner);
BindingContext bindingContext = resolveExtension.getContext(project, annotationOwner);
JavaDescriptorResolver javaDescriptorResolver = resolveExtension.getResolver(project, annotationOwner);
DeclarationDescriptor memberDescriptor = getDescriptorForMember(javaDescriptorResolver, annotationOwner);
if (memberDescriptor == null) return; if (memberDescriptor == null) return;
BindingContext bindingContext = KotlinCacheService.getInstance(project).getGlobalFacade(JvmPlatform.INSTANCE$)
.getFrontendService(annotationOwner, BindingTrace.class).getBindingContext();
List<String> errors = bindingContext.get(JavaBindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, memberDescriptor); List<String> errors = bindingContext.get(JavaBindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, memberDescriptor);
boolean hasSignatureAnnotation = KotlinSignatureUtil.findKotlinSignatureAnnotation(annotationOwner) != null; boolean hasSignatureAnnotation = KotlinSignatureUtil.findKotlinSignatureAnnotation(annotationOwner) != null;
@@ -134,26 +131,6 @@ public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider {
} }
} }
@Nullable
private static DeclarationDescriptor getDescriptorForMember(
@NotNull JavaDescriptorResolver javaDescriptorResolver,
@NotNull PsiModifierListOwner member
) {
if (member instanceof PsiMethod) {
PsiMethod method = (PsiMethod) member;
if (method.isConstructor()) {
return ResolvePackage.resolveConstructor(javaDescriptorResolver, new JavaConstructorImpl(method));
}
else {
return ResolvePackage.resolveMethod(javaDescriptorResolver, new JavaMethodImpl(method));
}
}
else if (member instanceof PsiField) {
return ResolvePackage.resolveField(javaDescriptorResolver, new JavaFieldImpl((PsiField) member));
}
return null;
}
public static boolean isMarkersEnabled(@NotNull Project project) { public static boolean isMarkersEnabled(@NotNull Project project) {
return PropertiesComponent.getInstance(project).getBoolean(SHOW_MARKERS_PROPERTY, true); return PropertiesComponent.getInstance(project).getBoolean(SHOW_MARKERS_PROPERTY, true);
} }