[psi] KtFile: add hasImportAlias with caching

We have hotspots in UAST due to aliases, so we can reduce the time
significantly by caching `hasImportAlias` property

^KTIJ-26688
This commit is contained in:
Dmitrii Gridin
2023-08-21 12:40:12 +02:00
committed by Space Team
parent efb96e31fb
commit 3d52ba3bca
2 changed files with 48 additions and 9 deletions
@@ -157,6 +157,9 @@ abstract class KtCodeFragment(
return null
}
override val importLists: List<KtImportList>
get() = importsAsImportList().let(::listOfNotNull)
override val importDirectives: List<KtImportDirective>
get() = importsAsImportList()?.imports ?: emptyList()
@@ -60,8 +60,20 @@ open class KtFile(viewProvider: FileViewProvider, val isCompiled: Boolean) :
val importList: KtImportList?
get() = importLists.firstOrNull()
private val importLists: Array<out KtImportList>
get() = findChildrenByTypeOrClass(KtStubElementTypes.IMPORT_LIST, KtImportList::class.java)
@Volatile
private var hasImportAlias: Boolean? = null
fun hasImportAlias(): Boolean {
val hasImportAlias = hasImportAlias
if (hasImportAlias != null) return hasImportAlias
val newValue = importLists.any(KtImportList::computeHasImportAlias)
this.hasImportAlias = newValue
return newValue
}
protected open val importLists: List<KtImportList>
get() = findChildrenByTypeOrClass(KtStubElementTypes.IMPORT_LIST, KtImportList::class.java).asList()
val fileAnnotationList: KtFileAnnotationList?
get() = findChildByTypeOrClass(KtStubElementTypes.FILE_ANNOTATION_LIST, KtFileAnnotationList::class.java)
@@ -179,15 +191,25 @@ open class KtFile(viewProvider: FileViewProvider, val isCompiled: Boolean) :
}
fun findImportByAlias(name: String): KtImportDirective? =
importDirectives.firstOrNull { name == it.aliasName }
fun findImportByAlias(name: String): KtImportDirective? {
if (!hasImportAlias()) return null
fun findAliasByFqName(fqName: FqName): KtImportAlias? = importDirectives.firstOrNull {
it.alias != null && fqName == it.importedFqName
}?.alias
return importDirectives.firstOrNull { name == it.aliasName }
}
fun getNameForGivenImportAlias(name: Name): Name? =
importDirectives.find { it.importedName == name }?.importedFqName?.pathSegments()?.last()
fun findAliasByFqName(fqName: FqName): KtImportAlias? {
if (!hasImportAlias()) return null
return importDirectives.firstOrNull {
it.alias != null && fqName == it.importedFqName
}?.alias
}
fun getNameForGivenImportAlias(name: Name): Name? {
if (!hasImportAlias()) return null
return importDirectives.find { it.importedName == name }?.importedFqName?.pathSegments()?.last()
}
@Deprecated("") // getPackageFqName should be used instead
override fun getPackageName(): String {
@@ -217,6 +239,7 @@ open class KtFile(viewProvider: FileViewProvider, val isCompiled: Boolean) :
isScript = null
hasTopLevelCallables = null
pathCached = null
hasImportAlias = null
}
fun isScript(): Boolean = isScript ?: stub?.isScript() ?: isScriptByTree
@@ -281,3 +304,16 @@ open class KtFile(viewProvider: FileViewProvider, val isCompiled: Boolean) :
val FILE_DECLARATION_TYPES = TokenSet.orSet(KtTokenSets.DECLARATION_TYPES, TokenSet.create(KtStubElementTypes.SCRIPT))
}
}
private fun KtImportList.computeHasImportAlias(): Boolean {
var child: PsiElement? = firstChild
while (child != null) {
if (child is KtImportDirective && child.alias != null) {
return true
}
child = child.nextSibling
}
return false
}