[LL FIR] reuse FirDesignation for LLFirResolveTarget

This is an intermediate change before unification

^KT-65345
This commit is contained in:
Dmitrii Gridin
2024-01-31 17:11:13 +01:00
committed by Space Team
parent 39131a7f30
commit eb8e3f64f0
11 changed files with 96 additions and 130 deletions
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.diagnostics.ConeDestructuringDeclarationsOnTopLevel
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol
@@ -63,6 +62,8 @@ class FirDesignation(
val path: List<FirDeclaration>,
val target: FirElementWithResolveState,
) {
constructor(target: FirElementWithResolveState) : this(emptyList(), target)
init {
for ((index, declaration) in path.withIndex()) {
when (declaration) {
@@ -93,14 +94,14 @@ class FirDesignation(
withFirDesignationEntry("designation", this@FirDesignation)
}
val fileOrNull: FirFile? get() = path.firstOrNull() as? FirFile
val fileOrNull: FirFile? get() = path.firstOrNull() as? FirFile ?: target as? FirFile
val script: FirScript
get() = scriptOrNull ?: errorWithAttachment("Script is not found") {
withFirDesignationEntry("designation", this@FirDesignation)
}
val scriptOrNull: FirScript? get() = path.getOrNull(0) as? FirScript ?: path.getOrNull(1) as? FirScript
val scriptOrNull: FirScript? get() = path.getOrNull(0) as? FirScript ?: path.getOrNull(1) as? FirScript ?: target as? FirScript
/**
* This property exists only for compatibility and should be dropped after KT-65345
@@ -131,6 +132,7 @@ private fun collectDesignationPath(target: FirElementWithResolveState): List<Fir
is FirConstructor,
is FirEnumEntry,
is FirPropertyAccessor,
is FirErrorProperty
-> {
requireIsInstance<FirCallableDeclaration>(target)
// We shouldn't try to build a designation path for such fake declarations as they
@@ -168,17 +170,8 @@ private fun collectDesignationPath(target: FirElementWithResolveState): List<Fir
}
}
is FirErrorProperty -> {
return if (target.diagnostic == ConeDestructuringDeclarationsOnTopLevel) emptyList() else null
}
is FirScript, is FirCodeFragment, is FirFileAnnotationsContainer -> {
return emptyList()
}
else -> {
return null
}
is FirScript, is FirCodeFragment, is FirFileAnnotationsContainer -> return emptyList()
else -> return null
}
}
@@ -1,34 +1,23 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.forEachDeclaration
import org.jetbrains.kotlin.fir.FirElementWithResolveState
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
/**
* [LLFirResolveTarget] representing a class with all callable members (functions and properties).
*/
internal class LLFirClassWithAllCallablesResolveTarget(
firFile: FirFile,
containerClasses: List<FirRegularClass>,
target: FirRegularClass,
) : LLFirResolveTarget(firFile, containerClasses, target) {
override fun visitTargetElement(
element: FirElementWithResolveState,
visitor: LLFirResolveTargetVisitor,
) {
visitor.performAction(element)
visitor.withRegularClass(element as FirRegularClass) {
element.forEachDeclaration {
if (it is FirCallableDeclaration) {
visitor.performAction(it)
}
internal class LLFirClassWithAllCallablesResolveTarget(designation: FirDesignation) : LLFirRegularClassResolveTarget(designation) {
override fun visitMembers(visitor: LLFirResolveTargetVisitor, firRegularClass: FirRegularClass) {
firRegularClass.forEachDeclaration {
if (it is FirCallableDeclaration) {
visitor.performAction(it)
}
}
}
@@ -1,30 +1,19 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.forEachDeclaration
import org.jetbrains.kotlin.fir.FirElementWithResolveState
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
/**
* [LLFirResolveTarget] representing a class with all class members to be resolved (this includes callables, init blocks, and classifiers)
*/
internal class LLFirClassWithAllMembersResolveTarget(
firFile: FirFile,
containerClasses: List<FirRegularClass>,
target: FirRegularClass,
) : LLFirResolveTarget(firFile, containerClasses, target) {
override fun visitTargetElement(
element: FirElementWithResolveState,
visitor: LLFirResolveTargetVisitor,
) {
visitor.performAction(element)
visitor.withRegularClass(element as FirRegularClass) {
element.forEachDeclaration(visitor::performAction)
}
internal class LLFirClassWithAllMembersResolveTarget(designation: FirDesignation) : LLFirRegularClassResolveTarget(designation) {
override fun visitMembers(visitor: LLFirResolveTargetVisitor, firRegularClass: FirRegularClass) {
firRegularClass.forEachDeclaration(visitor::performAction)
}
}
@@ -1,29 +1,20 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets
import org.jetbrains.kotlin.fir.FirElementWithResolveState
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
internal class LLFirClassWithSpecificMembersResolveTarget(
firFile: FirFile,
containerClasses: List<FirRegularClass>,
target: FirRegularClass,
designation: FirDesignation,
val members: List<FirDeclaration>,
) : LLFirResolveTarget(firFile, containerClasses, target) {
override fun visitTargetElement(
element: FirElementWithResolveState,
visitor: LLFirResolveTargetVisitor,
) {
visitor.performAction(element)
visitor.withRegularClass(element as FirRegularClass) {
members.forEach(visitor::performAction)
}
) : LLFirRegularClassResolveTarget(designation) {
override fun visitMembers(visitor: LLFirResolveTargetVisitor, firRegularClass: FirRegularClass) {
members.forEach(visitor::performAction)
}
override fun toStringAdditionalSuffix(): String = members.joinToString(prefix = "[", postfix = "]") { it.symbol.toString() }
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.withFirDesignationEntry
import org.jetbrains.kotlin.fir.FirElementWithResolveState
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.utils.exceptions.requireWithAttachment
internal sealed class LLFirRegularClassResolveTarget(designation: FirDesignation) : LLFirResolveTarget(designation) {
init {
requireWithAttachment(
target is FirRegularClass,
{ "Expected type of '${::target.name}' is ${FirRegularClass::class.simpleName}, but ${target::class.simpleName} is found" },
) {
withFirDesignationEntry("designation", this@LLFirRegularClassResolveTarget.designation)
}
}
abstract fun visitMembers(visitor: LLFirResolveTargetVisitor, firRegularClass: FirRegularClass)
final override fun visitTargetElement(
element: FirElementWithResolveState,
visitor: LLFirResolveTargetVisitor,
) {
visitor.performAction(element)
visitor.withRegularClass(element as FirRegularClass) {
visitMembers(visitor, element)
}
}
}
@@ -1,10 +1,11 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
import org.jetbrains.kotlin.fir.FirElementWithResolveState
import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer
@@ -22,32 +23,30 @@ import org.jetbrains.kotlin.fir.declarations.FirScript
*
* Specifies the path to resolve targets and resolve targets themselves.
* Those targets are going to be resolved by [LLFirModuleLazyDeclarationResolver][org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.LLFirModuleLazyDeclarationResolver].
*
* @see FirDesignation
*/
internal sealed class LLFirResolveTarget(
internal sealed class LLFirResolveTarget(val designation: FirDesignation) {
/**
* [FirFile] where the targets are located.
* Can be null if [target] does not belong to any file.
* E.g., fake overrides.
* @see org.jetbrains.kotlin.fir.scopes.impl.FirFakeOverrideGenerator
*/
val firFile: FirFile?,
val firFile: FirFile? get() = designation.fileOrNull
/**
* The list of [FirRegularClass] which are the required to go from file to target declarations in the top-down order.
* The list of [FirFile], [FirScript] and [FirRegularClass] which are
* the required to go from file to target declarations in the top-down order.
*
* If resolve target is [FirFile], [FirScript] or [FirRegularClass] itself, it's not included into the [path].
*/
containerClasses: List<FirRegularClass>,
val path: List<FirDeclaration> get() = designation.path
/**
* A dedicated main element.
*/
val target: FirElementWithResolveState,
) {
/**
* The list of [FirScript] and [FirRegularClass] which are the required to go from file to target declarations in the top-down order.
*
* If resolve target is [FirRegularClass] or [FirScript] itself, it's not included into the [path].
*/
val path: List<FirDeclaration> = pathWithScript(firFile, containerClasses, target)
val target: FirElementWithResolveState get() = designation.target
/**
* Visit [path], [target] and optionally its subgraph.
@@ -59,13 +58,7 @@ internal sealed class LLFirResolveTarget(
visitor.performAction(target)
}
if (firFile != null) {
visitor.withFile(firFile) {
goToTarget(visitor)
}
} else {
goToTarget(visitor)
}
goToTarget(visitor)
}
private fun goToTarget(visitor: LLFirResolveTargetVisitor) {
@@ -81,6 +74,7 @@ internal sealed class LLFirResolveTarget(
when (val declaration = pathIterator.next()) {
is FirRegularClass -> visitor.withRegularClass(declaration) { goToTarget(pathIterator, visitor) }
is FirScript -> visitor.withScript(declaration) { goToTarget(pathIterator, visitor) }
is FirFile -> visitor.withFile(declaration) { goToTarget(pathIterator, visitor) }
else -> errorWithFirSpecificEntries(
"Unexpected declaration in path: ${declaration::class.simpleName}",
fir = declaration,
@@ -114,9 +108,9 @@ internal sealed class LLFirResolveTarget(
append(this@LLFirResolveTarget::class.simpleName)
append("(")
buildList {
firFile?.name?.let(::add)
path.mapTo(this) {
when (it) {
is FirFile -> it.name
is FirRegularClass -> it.name
is FirScript -> it.name
else -> errorWithFirSpecificEntries("Unsupported path declaration: ${it::class.simpleName}", fir = it)
@@ -131,19 +125,13 @@ internal sealed class LLFirResolveTarget(
protected open fun toStringAdditionalSuffix(): String? = null
private fun toStringForTarget(): String = when (target) {
private fun toStringForTarget(): String = when (val fir = target) {
is FirConstructor -> "constructor"
is FirClassLikeDeclaration -> target.symbol.name.asString()
is FirCallableDeclaration -> target.symbol.name.asString()
is FirClassLikeDeclaration -> fir.symbol.name.asString()
is FirCallableDeclaration -> fir.symbol.name.asString()
is FirAnonymousInitializer -> ("<init-block>")
is FirFileAnnotationsContainer -> "<file annotations>"
is FirScript -> target.name.asString()
is FirScript -> fir.name.asString()
else -> "???"
}
}
private fun pathWithScript(firFile: FirFile?, path: List<FirRegularClass>, target: FirElementWithResolveState): List<FirDeclaration> {
if (firFile == null || target is FirFile || target is FirFileAnnotationsContainer || target is FirScript) return path
val firScript = firFile.declarations.singleOrNull() as? FirScript ?: return path
return listOf(firScript) + path
}
@@ -1,27 +1,18 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation
import org.jetbrains.kotlin.fir.FirElementWithResolveState
import org.jetbrains.kotlin.fir.declarations.*
/**
* [LLFirResolveTarget] representing single target to resolve. The [target] can be any of [FirElementWithResolveState]
*/
internal class LLFirSingleResolveTarget : LLFirResolveTarget {
constructor(firFile: FirFile) : super(firFile, emptyList(), firFile)
constructor(
firFile: FirFile,
containerClasses: List<FirRegularClass>,
target: FirElementWithResolveState,
) : super(firFile, containerClasses, target)
constructor(target: FirElementWithResolveState) : super(null, emptyList(), target)
internal class LLFirSingleResolveTarget(designation: FirDesignation) : LLFirResolveTarget(designation) {
override fun visitTargetElement(
element: FirElementWithResolveState,
visitor: LLFirResolveTargetVisitor,
@@ -1,10 +1,11 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.forEachDeclaration
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.isDeclarationContainer
@@ -18,13 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.FirScript
* [LLFirResolveTarget] representing all declarations in [target] recursively.
* All of them are going to be resolved.
*/
internal class LLFirWholeElementResolveTarget(
firFile: FirFile,
containerClasses: List<FirRegularClass>,
target: FirElementWithResolveState,
) : LLFirResolveTarget(firFile, containerClasses, target) {
constructor(firFile: FirFile) : this(firFile, emptyList(), firFile)
internal class LLFirWholeElementResolveTarget(designation: FirDesignation) : LLFirResolveTarget(designation) {
override fun visitTargetElement(
element: FirElementWithResolveState,
visitor: LLFirResolveTargetVisitor,
@@ -42,7 +37,7 @@ internal class LLFirWholeElementResolveTarget(
}
}
element is FirFile -> {
element is FirFile -> visitor.withFile(element) {
element.forEachDeclaration {
visitTargetElement(it, visitor)
}
@@ -12,11 +12,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
internal fun FirDesignation.asResolveTarget(): LLFirSingleResolveTarget = LLFirSingleResolveTarget(
file,
classPath,
target,
)
internal fun FirDesignation.asResolveTarget(): LLFirSingleResolveTarget = LLFirSingleResolveTarget(this)
/**
* Resolves the target to the specified [phase].
@@ -32,4 +28,4 @@ internal fun LLFirResolveTarget.resolve(phase: FirResolvePhase) {
lazyDeclarationResolver.lazyResolveTarget(this, phase, towerDataContextCollector = null)
}
internal val LLFirResolveTarget.session: LLFirSession get() = target.llFirSession
internal val LLFirResolveTarget.session: LLFirSession get() = target.llFirSession
@@ -57,9 +57,7 @@ internal object FileElementFactory {
val firClassDesignation = firClass.collectDesignationWithFile()
val designationWithMembers = LLFirClassWithSpecificMembersResolveTarget(
firClassDesignation.file,
firClassDesignation.classPath,
firClass,
firClassDesignation,
classMembersToResolve,
)
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignation
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirClassWithAllCallablesResolveTarget
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirSingleResolveTarget
@@ -21,7 +22,7 @@ import org.jetbrains.kotlin.fir.isCopyCreatedInScope
internal object LLFirResolveMultiDesignationCollector {
fun getDesignationsToResolve(target: FirElementWithResolveState): List<LLFirResolveTarget> = when (target) {
is FirFile -> listOf(LLFirSingleResolveTarget(target))
is FirFile -> listOf(FirDesignation(target).asResolveTarget())
is FirSyntheticPropertyAccessor -> getDesignationsToResolve(target.delegate)
is FirSyntheticProperty -> getDesignationsToResolve(target.getter) + target.setter?.let(::getDesignationsToResolve).orEmpty()
else -> listOfNotNull(getMainDesignationToResolve(target))
@@ -29,20 +30,20 @@ internal object LLFirResolveMultiDesignationCollector {
fun getDesignationsToResolveWithCallableMembers(target: FirRegularClass): List<LLFirResolveTarget> {
val designation = target.tryCollectDesignationWithFile() ?: return emptyList()
val resolveTarget = LLFirClassWithAllCallablesResolveTarget(designation.file, designation.classPath, target)
val resolveTarget = LLFirClassWithAllCallablesResolveTarget(designation)
return listOf(resolveTarget)
}
fun getDesignationsToResolveRecursively(target: FirElementWithResolveState): List<LLFirResolveTarget> {
if (target is FirFile) return listOf(LLFirWholeElementResolveTarget(target))
if (target is FirFile) return listOf(LLFirWholeElementResolveTarget(FirDesignation(target)))
if (!target.shouldBeResolved()) return emptyList()
if (target is FirCallableDeclaration && target.isCopyCreatedInScope) {
return listOf(LLFirSingleResolveTarget(target))
return listOf(FirDesignation(target).asResolveTarget())
}
val designation = target.tryCollectDesignationWithFile() ?: return emptyList()
val resolveTarget = LLFirWholeElementResolveTarget(designation.file, designation.classPath, target)
val resolveTarget = LLFirWholeElementResolveTarget(designation)
return listOf(resolveTarget)
}
@@ -54,7 +55,7 @@ internal object LLFirResolveMultiDesignationCollector {
target is FirBackingField -> getMainDesignationToResolve(target.propertySymbol.fir)
target is FirTypeParameter -> getMainDesignationToResolve(target.containingDeclarationSymbol.fir)
target is FirValueParameter -> getMainDesignationToResolve(target.containingFunctionSymbol.fir)
target is FirCallableDeclaration && target.isCopyCreatedInScope -> LLFirSingleResolveTarget(target)
target is FirCallableDeclaration && target.isCopyCreatedInScope -> FirDesignation(target).asResolveTarget()
else -> target.tryCollectDesignationWithFile()?.asResolveTarget()
}
}