From e1627493660f5a893604afe51c31fd716fa5c4f4 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 22 Mar 2018 13:07:59 +0300 Subject: [PATCH] Add a cache for PsiBasedClassResolver instances The PsiBasedClassResolver constructor isn't very cheap to call because it runs computation of conflicting names each time Again, this is helpful for Spring-interop because PsiBasedClassResolver is used very frequently there #KT-23380 Fixed --- .../IdeLightClassInheritanceHelper.kt | 2 +- .../idea/search/PsiBasedClassResolver.kt | 28 +++++++++++++++++-- .../KotlinAnnotatedElementsSearcher.kt | 2 +- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/IdeLightClassInheritanceHelper.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/IdeLightClassInheritanceHelper.kt index 71dc8af70bc..b2d5014cc65 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/IdeLightClassInheritanceHelper.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/lightClasses/IdeLightClassInheritanceHelper.kt @@ -52,7 +52,7 @@ class IdeLightClassInheritanceHelper : LightClassInheritanceHelper { } private fun isAmongEntries(baseClass: PsiClass, entries: List): ImpreciseResolveResult { - val psiBasedResolver = PsiBasedClassResolver(baseClass) + val psiBasedResolver = PsiBasedClassResolver.getInstance(baseClass) entries@ for (entry in entries) { val reference: KtSimpleNameExpression = entry.typeAsUserType?.referenceExpression ?: continue@entries when (psiBasedResolver.canBeTargetReference(reference)) { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/PsiBasedClassResolver.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/PsiBasedClassResolver.kt index 3b68fc3a692..ffd8b3fa587 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/PsiBasedClassResolver.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/PsiBasedClassResolver.kt @@ -16,9 +16,14 @@ package org.jetbrains.kotlin.idea.search +import com.intellij.openapi.util.Key import com.intellij.psi.PsiClass import com.intellij.psi.PsiModifier import com.intellij.psi.search.PsiShortNamesCache +import com.intellij.psi.util.CachedValue +import com.intellij.psi.util.CachedValueProvider +import com.intellij.psi.util.CachedValuesManager +import com.intellij.psi.util.PsiModificationTracker import org.jetbrains.annotations.TestOnly import org.jetbrains.kotlin.asJava.ImpreciseResolveResult import org.jetbrains.kotlin.asJava.ImpreciseResolveResult.* @@ -61,9 +66,28 @@ class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName: @TestOnly val attempts = AtomicInteger() @TestOnly val trueHits = AtomicInteger() @TestOnly val falseHits = AtomicInteger() + + private val PSI_BASED_CLASS_RESOLVER_KEY = Key>("PsiBasedClassResolver") + + fun getInstance(target: PsiClass): PsiBasedClassResolver { + target.getUserData(PSI_BASED_CLASS_RESOLVER_KEY)?.let { return it.value } + + val cachedValue = CachedValuesManager.getManager(target.project).createCachedValue( + { + CachedValueProvider.Result( + PsiBasedClassResolver(target), + PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT + ) + }, false + ) + + target.putUserData(PSI_BASED_CLASS_RESOLVER_KEY, cachedValue) + + return cachedValue.value + } } - constructor(target: PsiClass): this(target.qualifiedName ?: "") { + private constructor(target: PsiClass): this(target.qualifiedName ?: "") { if (target.qualifiedName == null || target.containingClass != null || targetPackage.isEmpty()) { forceAmbiguity = true return @@ -239,4 +263,4 @@ private fun KtFile.getDefaultImports(): List { return TargetPlatformDetector.getPlatform(this).getDefaultImports( versionSettings.supportsFeature(LanguageFeature.DefaultImportOfPackageKotlinComparisons) ) -} \ No newline at end of file +} diff --git a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinAnnotatedElementsSearcher.kt b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinAnnotatedElementsSearcher.kt index 8ec81434948..296cc08e590 100644 --- a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinAnnotatedElementsSearcher.kt +++ b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinAnnotatedElementsSearcher.kt @@ -78,7 +78,7 @@ class KotlinAnnotatedElementsSearcher : QueryExecutor Boolean): Boolean { assert(annClass.isAnnotationType) { "Annotation type should be passed to annotated members search" } - val psiBasedClassResolver = PsiBasedClassResolver(annClass) + val psiBasedClassResolver = PsiBasedClassResolver.getInstance(annClass) val annotationFQN = annClass.qualifiedName!! val candidates = getKotlinAnnotationCandidates(annClass, useScope)