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:
+8
-1
@@ -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 {
|
||||
|
||||
+25
-6
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user