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 {
|
override fun analyze(elements: Collection<KtElement>, bodyResolveMode: BodyResolveMode): BindingContext {
|
||||||
ResolveInDispatchThreadManager.assertNoResolveInDispatchThread()
|
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)
|
val resolveElementCache = getFrontendService(elements.first(), ResolveElementCache::class.java)
|
||||||
return runWithCancellationCheck {
|
return runWithCancellationCheck {
|
||||||
|
|||||||
+25
-6
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.psi.KtElement
|
|||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.CompositeBindingContext
|
import org.jetbrains.kotlin.resolve.CompositeBindingContext
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
|
import java.util.concurrent.locks.ReentrantLock
|
||||||
|
|
||||||
internal class ProjectResolutionFacade(
|
internal class ProjectResolutionFacade(
|
||||||
private val debugString: String,
|
private val debugString: String,
|
||||||
@@ -50,12 +51,34 @@ internal class ProjectResolutionFacade(
|
|||||||
{
|
{
|
||||||
val resolverForProject = cachedResolverForProject
|
val resolverForProject = cachedResolverForProject
|
||||||
val results = object : SLRUCache<KtFile, PerFileAnalysisCache>(2, 3) {
|
val results = object : SLRUCache<KtFile, PerFileAnalysisCache>(2, 3) {
|
||||||
|
private val lock = ReentrantLock()
|
||||||
|
|
||||||
override fun createValue(file: KtFile): PerFileAnalysisCache {
|
override fun createValue(file: KtFile): PerFileAnalysisCache {
|
||||||
return PerFileAnalysisCache(
|
return PerFileAnalysisCache(
|
||||||
file,
|
file,
|
||||||
resolverForProject.resolverForModule(file.getModuleInfo()).componentProvider
|
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(
|
val allDependencies = resolverForProjectDependencies + listOf(
|
||||||
@@ -121,9 +144,7 @@ internal class ProjectResolutionFacade(
|
|||||||
analysisResults.value!!
|
analysisResults.value!!
|
||||||
}
|
}
|
||||||
val results = elements.map {
|
val results = elements.map {
|
||||||
val perFileCache = synchronized(slruCache) {
|
val perFileCache = slruCache[it.containingKtFile]
|
||||||
slruCache[it.containingKtFile]
|
|
||||||
}
|
|
||||||
perFileCache.getAnalysisResults(it)
|
perFileCache.getAnalysisResults(it)
|
||||||
}
|
}
|
||||||
val withError = results.firstOrNull { it.isError() }
|
val withError = results.firstOrNull { it.isError() }
|
||||||
@@ -140,9 +161,7 @@ internal class ProjectResolutionFacade(
|
|||||||
val slruCache = synchronized(analysisResults) {
|
val slruCache = synchronized(analysisResults) {
|
||||||
analysisResults.upToDateOrNull?.get() ?: return null
|
analysisResults.upToDateOrNull?.get() ?: return null
|
||||||
}
|
}
|
||||||
val perFileCache = synchronized(slruCache) {
|
val perFileCache = slruCache.getIfCached(element.containingKtFile)
|
||||||
slruCache.getIfCached(element.containingKtFile)
|
|
||||||
}
|
|
||||||
return perFileCache?.fetchAnalysisResults(element)
|
return perFileCache?.fetchAnalysisResults(element)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user