Fetch analysis results if it is available

The general idea is to try to fetch a full analysis if it is existed in PerFileAnalysisCache instead of go to ResolveElementCache and do analysis there. Do not perform analysis if it is not in PerFileAnalysisCache.

#KT-37467 Fixed
This commit is contained in:
Vladimir Dolzhenko
2020-04-03 22:02:10 +02:00
parent 3742fe4871
commit e73a573885
2 changed files with 33 additions and 7 deletions
@@ -57,7 +57,14 @@ internal class ModuleResolutionFacadeImpl(
override fun analyze(elements: Collection<KtElement>, bodyResolveMode: BodyResolveMode): BindingContext {
ResolveInDispatchThreadManager.assertNoResolveInDispatchThread()
if (elements.isEmpty()) return BindingContext.EMPTY
when (elements.size) {
0 -> return BindingContext.EMPTY
1 -> {
runWithCancellationCheck {
projectFacade.fetchAnalysisResultsForElement(elements.first())?.bindingContext
}?.let { return it }
}
}
val resolveElementCache = getFrontendService(elements.first(), ResolveElementCache::class.java)
return runWithCancellationCheck {
@@ -21,6 +21,7 @@ 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
import java.util.concurrent.locks.ReentrantLock
internal class ProjectResolutionFacade(
private val debugString: String,
@@ -50,12 +51,34 @@ internal class ProjectResolutionFacade(
{
val resolverForProject = cachedResolverForProject
val results = object : SLRUCache<KtFile, PerFileAnalysisCache>(2, 3) {
private val lock = ReentrantLock()
override fun createValue(file: KtFile): PerFileAnalysisCache {
return PerFileAnalysisCache(
file,
resolverForProject.resolverForModule(file.getModuleInfo()).componentProvider
)
}
override fun get(key: KtFile?): PerFileAnalysisCache {
lock.lock()
try {
return super.get(key)
} finally {
lock.unlock()
}
}
override fun getIfCached(key: KtFile?): PerFileAnalysisCache? {
if (lock.tryLock()) {
try {
return super.getIfCached(key)
} finally {
lock.unlock()
}
}
return null
}
}
val allDependencies = resolverForProjectDependencies + listOf(
@@ -121,9 +144,7 @@ internal class ProjectResolutionFacade(
analysisResults.value!!
}
val results = elements.map {
val perFileCache = synchronized(slruCache) {
slruCache[it.containingKtFile]
}
val perFileCache = slruCache[it.containingKtFile]
perFileCache.getAnalysisResults(it)
}
val withError = results.firstOrNull { it.isError() }
@@ -140,9 +161,7 @@ internal class ProjectResolutionFacade(
val slruCache = synchronized(analysisResults) {
analysisResults.upToDateOrNull?.get() ?: return null
}
val perFileCache = synchronized(slruCache) {
slruCache.getIfCached(element.containingKtFile)
}
val perFileCache = slruCache.getIfCached(element.containingKtFile)
return perFileCache?.fetchAnalysisResults(element)
}