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.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.FileStructureCache
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureElement
|
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.fir.low.level.api.util.isNonAnonymousClassOrObject
|
||||||
import org.jetbrains.kotlin.idea.util.getElementTextInContext
|
import org.jetbrains.kotlin.idea.util.getElementTextInContext
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -112,7 +112,7 @@ internal inline fun PsiElement.getNonLocalContainingOrThisDeclaration(predicate:
|
|||||||
if (container is KtNamedDeclaration
|
if (container is KtNamedDeclaration
|
||||||
&& (container.isNonAnonymousClassOrObject() || container is KtDeclarationWithBody || container is KtProperty || container is KtTypeAlias)
|
&& (container.isNonAnonymousClassOrObject() || container is KtDeclarationWithBody || container is KtProperty || container is KtTypeAlias)
|
||||||
&& container !is KtPrimaryConstructor
|
&& container !is KtPrimaryConstructor
|
||||||
&& container.hasFqName()
|
&& FirLazyDeclarationResolver.declarationCanBeLazilyResolved(container)
|
||||||
&& container !is KtEnumEntry
|
&& container !is KtEnumEntry
|
||||||
&& container !is KtFunctionLiteral
|
&& container !is KtFunctionLiteral
|
||||||
&& container.containingClassOrObject !is KtEnumEntry
|
&& 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.file.builder.ModuleFileCache
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
|
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.providers.FirIdeProvider
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.hasFqName
|
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
|
||||||
internal sealed class FileStructureElement(val firFile: FirFile, protected val lockProvider: LockProvider<FirFile>) {
|
internal sealed class FileStructureElement(val firFile: FirFile, protected val lockProvider: LockProvider<FirFile>) {
|
||||||
@@ -162,14 +161,14 @@ internal class NonReanalyzableDeclarationStructureElement(
|
|||||||
private val recorder = object : FirElementsRecorder() {
|
private val recorder = object : FirElementsRecorder() {
|
||||||
override fun visitProperty(property: FirProperty, data: MutableMap<KtElement, FirElement>) {
|
override fun visitProperty(property: FirProperty, data: MutableMap<KtElement, FirElement>) {
|
||||||
val psi = property.psi as? KtProperty ?: return super.visitProperty(property, data)
|
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)
|
super.visitProperty(property, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: MutableMap<KtElement, FirElement>) {
|
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: MutableMap<KtElement, FirElement>) {
|
||||||
val psi = simpleFunction.psi as? KtNamedFunction ?: return super.visitSimpleFunction(simpleFunction, data)
|
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)
|
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.render
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
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.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.idea.fir.low.level.api.util.replaceFirst
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
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 KtClassOrObject && ktDeclaration !is KtDeclarationWithBody && ktDeclaration !is KtProperty && ktDeclaration !is KtTypeAlias -> false
|
||||||
ktDeclaration is KtEnumEntry -> false
|
ktDeclaration is KtEnumEntry -> false
|
||||||
ktDeclaration.containingClassOrObject 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<*>) {
|
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.trasformers.FirFileAnnotationsResolveTransformer
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.*
|
import org.jetbrains.kotlin.idea.fir.low.level.api.util.*
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||||
|
|
||||||
internal class FirLazyDeclarationResolver(
|
internal class FirLazyDeclarationResolver(
|
||||||
private val firFileBuilder: FirFileBuilder
|
private val firFileBuilder: FirFileBuilder
|
||||||
@@ -235,7 +236,7 @@ internal class FirLazyDeclarationResolver(
|
|||||||
private fun FirDeclaration.getNonLocalDeclarationToResolve(provider: FirProvider, moduleFileCache: ModuleFileCache): FirDeclaration {
|
private fun FirDeclaration.getNonLocalDeclarationToResolve(provider: FirProvider, moduleFileCache: ModuleFileCache): FirDeclaration {
|
||||||
if (this is FirFile) return this
|
if (this is FirFile) return this
|
||||||
val ktDeclaration = psi as? KtDeclaration ?: error("FirDeclaration should have a PSI of type KtDeclaration")
|
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()
|
val nonLocalPsi = ktDeclaration.getNonLocalContainingOrThisDeclaration()
|
||||||
?: error("Container for local declaration cannot be null")
|
?: error("Container for local declaration cannot be null")
|
||||||
return nonLocalPsi.findSourceNonLocalFirDeclaration(firFileBuilder, provider.symbolProvider, moduleFileCache)
|
return nonLocalPsi.findSourceNonLocalFirDeclaration(firFileBuilder, provider.symbolProvider, moduleFileCache)
|
||||||
@@ -243,5 +244,26 @@ internal class FirLazyDeclarationResolver(
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val LAST_NON_LAZY_PHASE = FirResolvePhase.STATUS
|
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()
|
return result.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun KtDeclaration.hasFqName(): Boolean =
|
|
||||||
parentsOfType<KtDeclaration>(withSelf = false).all { it.isNonAnonymousClassOrObject() }
|
|
||||||
|
|
||||||
internal fun KtDeclaration.isNonAnonymousClassOrObject() =
|
internal fun KtDeclaration.isNonAnonymousClassOrObject() =
|
||||||
this is KtClassOrObject
|
this is KtClassOrObject
|
||||||
&& !this.isObjectLiteral()
|
&& !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.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.render
|
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.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.KotlinLightCodeInsightFixtureTestCase
|
||||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -29,7 +29,9 @@ abstract class AbstractFirLazyDeclarationResolveTest : KotlinLightCodeInsightFix
|
|||||||
fun doTest(path: String) {
|
fun doTest(path: String) {
|
||||||
val testDataFile = File(path)
|
val testDataFile = File(path)
|
||||||
val ktFile = myFixture.configureByText(testDataFile.name, FileUtil.loadFile(testDataFile)) as KtFile
|
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" }
|
val declarationToResolve = lazyDeclarations.firstOrNull { it.name?.lowercase() == "resolveme" }
|
||||||
?: error("declaration with name `resolveMe` was not found")
|
?: error("declaration with name `resolveMe` was not found")
|
||||||
|
|||||||
Reference in New Issue
Block a user