FIR IDE: introduce single function for checking if declaration can be lazily resolved
This commit is contained in:
+2
-2
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureCache
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureElement
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.hasFqName
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.isNonAnonymousClassOrObject
|
||||
import org.jetbrains.kotlin.idea.util.getElementTextInContext
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -112,7 +112,7 @@ internal inline fun PsiElement.getNonLocalContainingOrThisDeclaration(predicate:
|
||||
if (container is KtNamedDeclaration
|
||||
&& (container.isNonAnonymousClassOrObject() || container is KtDeclarationWithBody || container is KtProperty || container is KtTypeAlias)
|
||||
&& container !is KtPrimaryConstructor
|
||||
&& container.hasFqName()
|
||||
&& FirLazyDeclarationResolver.declarationCanBeLazilyResolved(container)
|
||||
&& container !is KtEnumEntry
|
||||
&& container !is KtFunctionLiteral
|
||||
&& container.containingClassOrObject !is KtEnumEntry
|
||||
|
||||
+2
-3
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.LockProvider
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.FirIdeProvider
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.hasFqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
internal sealed class FileStructureElement(val firFile: FirFile, protected val lockProvider: LockProvider<FirFile>) {
|
||||
@@ -162,14 +161,14 @@ internal class NonReanalyzableDeclarationStructureElement(
|
||||
private val recorder = object : FirElementsRecorder() {
|
||||
override fun visitProperty(property: FirProperty, data: MutableMap<KtElement, FirElement>) {
|
||||
val psi = property.psi as? KtProperty ?: return super.visitProperty(property, data)
|
||||
if (!FileElementFactory.isReanalyzableContainer(psi) || !psi.hasFqName()) {
|
||||
if (!FileElementFactory.isReanalyzableContainer(psi) || !FirLazyDeclarationResolver.declarationCanBeLazilyResolved(psi)) {
|
||||
super.visitProperty(property, data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: MutableMap<KtElement, FirElement>) {
|
||||
val psi = simpleFunction.psi as? KtNamedFunction ?: return super.visitSimpleFunction(simpleFunction, data)
|
||||
if (!FileElementFactory.isReanalyzableContainer(psi) || !psi.hasFqName()) {
|
||||
if (!FileElementFactory.isReanalyzableContainer(psi) || !FirLazyDeclarationResolver.declarationCanBeLazilyResolved(psi)) {
|
||||
super.visitSimpleFunction(simpleFunction, data)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.replaceFirst
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
@@ -22,7 +23,8 @@ internal object FileStructureUtil {
|
||||
ktDeclaration !is KtClassOrObject && ktDeclaration !is KtDeclarationWithBody && ktDeclaration !is KtProperty && ktDeclaration !is KtTypeAlias -> false
|
||||
ktDeclaration is KtEnumEntry -> false
|
||||
ktDeclaration.containingClassOrObject is KtEnumEntry -> false
|
||||
else -> !KtPsiUtil.isLocal(ktDeclaration)
|
||||
ktDeclaration is KtNamedDeclaration -> !FirLazyDeclarationResolver.declarationCanBeLazilyResolved(ktDeclaration)
|
||||
else -> false
|
||||
}
|
||||
|
||||
fun replaceDeclaration(firFile: FirFile, from: FirCallableDeclaration<*>, to: FirCallableDeclaration<*>) {
|
||||
|
||||
+23
-1
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.trasformers.FirDesignatedImpl
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.trasformers.FirFileAnnotationsResolveTransformer
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
|
||||
internal class FirLazyDeclarationResolver(
|
||||
private val firFileBuilder: FirFileBuilder
|
||||
@@ -235,7 +236,7 @@ internal class FirLazyDeclarationResolver(
|
||||
private fun FirDeclaration.getNonLocalDeclarationToResolve(provider: FirProvider, moduleFileCache: ModuleFileCache): FirDeclaration {
|
||||
if (this is FirFile) return this
|
||||
val ktDeclaration = psi as? KtDeclaration ?: error("FirDeclaration should have a PSI of type KtDeclaration")
|
||||
if (!KtPsiUtil.isLocal(ktDeclaration)) return this
|
||||
if (declarationCanBeLazilyResolved(ktDeclaration)) return this
|
||||
val nonLocalPsi = ktDeclaration.getNonLocalContainingOrThisDeclaration()
|
||||
?: error("Container for local declaration cannot be null")
|
||||
return nonLocalPsi.findSourceNonLocalFirDeclaration(firFileBuilder, provider.symbolProvider, moduleFileCache)
|
||||
@@ -243,5 +244,26 @@ internal class FirLazyDeclarationResolver(
|
||||
|
||||
companion object {
|
||||
private val LAST_NON_LAZY_PHASE = FirResolvePhase.STATUS
|
||||
|
||||
fun declarationCanBeLazilyResolved(declaration: KtDeclaration): Boolean {
|
||||
return when (declaration) {
|
||||
!is KtNamedDeclaration -> false
|
||||
is KtDestructuringDeclarationEntry, is KtFunctionLiteral, is KtTypeParameter -> false
|
||||
is KtPrimaryConstructor -> false
|
||||
is KtParameter -> {
|
||||
if (declaration.hasValOrVar()) declaration.containingClassOrObject?.getClassId() != null
|
||||
else false
|
||||
}
|
||||
is KtCallableDeclaration, is KtEnumEntry -> {
|
||||
when (val parent = declaration.parent) {
|
||||
is KtFile -> true
|
||||
is KtClassBody -> (parent.parent as? KtClassOrObject)?.getClassId() != null
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
is KtClassLikeDeclaration -> declaration.getClassId() != null
|
||||
else -> error("Unexpected ${declaration::class.qualifiedName}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-3
@@ -93,9 +93,6 @@ internal fun IdeaModuleInfo.collectTransitiveDependenciesWithSelf(): List<IdeaMo
|
||||
return result.toList()
|
||||
}
|
||||
|
||||
internal fun KtDeclaration.hasFqName(): Boolean =
|
||||
parentsOfType<KtDeclaration>(withSelf = false).all { it.isNonAnonymousClassOrObject() }
|
||||
|
||||
internal fun KtDeclaration.isNonAnonymousClassOrObject() =
|
||||
this is KtClassOrObject
|
||||
&& !this.isObjectLiteral()
|
||||
|
||||
+4
-2
@@ -11,11 +11,11 @@ import org.jetbrains.kotlin.fir.FirRenderer
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.withFirDeclaration
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.io.File
|
||||
@@ -29,7 +29,9 @@ abstract class AbstractFirLazyDeclarationResolveTest : KotlinLightCodeInsightFix
|
||||
fun doTest(path: String) {
|
||||
val testDataFile = File(path)
|
||||
val ktFile = myFixture.configureByText(testDataFile.name, FileUtil.loadFile(testDataFile)) as KtFile
|
||||
val lazyDeclarations = ktFile.collectDescendantsOfType<KtDeclaration> { ktDeclaration -> !KtPsiUtil.isLocal(ktDeclaration) }
|
||||
val lazyDeclarations = ktFile.collectDescendantsOfType<KtDeclaration> { ktDeclaration ->
|
||||
FirLazyDeclarationResolver.declarationCanBeLazilyResolved(ktDeclaration)
|
||||
}
|
||||
|
||||
val declarationToResolve = lazyDeclarations.firstOrNull { it.name?.lowercase() == "resolveme" }
|
||||
?: error("declaration with name `resolveMe` was not found")
|
||||
|
||||
Reference in New Issue
Block a user