[FIR] Resolve statuses of all classes on path in FirDesignatedStatusResolveTransformer
This is required for calculating of effective visibility, because it depends on effective visibility of outer class (those changes are added in next commit) Also fix incorrect designation building for local classes
This commit is contained in:
committed by
TeamCityServer
parent
220f8a9169
commit
a600d18396
+50
-44
@@ -12,14 +12,12 @@ import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.LocalClassesNavigationInfo
|
||||
import org.jetbrains.kotlin.fir.scopes.FirCompositeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.classId
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||
import org.jetbrains.kotlin.fir.visitors.compose
|
||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
@@ -143,7 +141,7 @@ private class FirDesignatedStatusResolveTransformer(
|
||||
}
|
||||
currentElement = null
|
||||
}
|
||||
return false
|
||||
return !result
|
||||
}
|
||||
|
||||
override fun FirDeclaration.needResolveMembers(): Boolean {
|
||||
@@ -172,6 +170,11 @@ private class FirDesignatedStatusResolveTransformer(
|
||||
updateResolvePhaseOfMembers(regularClass)
|
||||
regularClass.transformStatus(this, statusResolver.resolveStatus(regularClass, containingClass, isLocal = false))
|
||||
}
|
||||
} else {
|
||||
if (regularClass.status !is FirResolvedDeclarationStatus) {
|
||||
regularClass.transformStatus(this, statusResolver.resolveStatus(regularClass, containingClass, isLocal = false))
|
||||
statusComputationSession.computeOnlyClassStatus(regularClass)
|
||||
}
|
||||
}
|
||||
return transformClass(regularClass, data).also {
|
||||
if (classLocated) statusComputationSession.endComputing(regularClass)
|
||||
@@ -184,9 +187,13 @@ sealed class StatusComputationSession {
|
||||
|
||||
abstract fun startComputing(klass: FirClass<*>): StatusComputationStatus
|
||||
abstract fun endComputing(klass: FirClass<*>)
|
||||
abstract fun computeOnlyClassStatus(klass: FirClass<*>)
|
||||
|
||||
enum class StatusComputationStatus {
|
||||
NotComputed, Computing, Computed
|
||||
enum class StatusComputationStatus(val requiresComputation: Boolean) {
|
||||
NotComputed(true),
|
||||
Computing(false),
|
||||
ComputedOnlyClassStatus(true),
|
||||
Computed(false)
|
||||
}
|
||||
|
||||
class Regular : StatusComputationSession() {
|
||||
@@ -202,6 +209,13 @@ sealed class StatusComputationSession {
|
||||
override fun endComputing(klass: FirClass<*>) {
|
||||
statusMap[klass] = StatusComputationStatus.Computed
|
||||
}
|
||||
|
||||
override fun computeOnlyClassStatus(klass: FirClass<*>) {
|
||||
val existedStatus = statusMap.getValue(klass)
|
||||
if (existedStatus < StatusComputationStatus.ComputedOnlyClassStatus) {
|
||||
statusMap[klass] = StatusComputationStatus.ComputedOnlyClassStatus
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ForLocalClassResolution(private val localClasses: Set<FirClassLikeDeclaration<*>>) : StatusComputationSession() {
|
||||
@@ -219,6 +233,10 @@ sealed class StatusComputationSession {
|
||||
override fun endComputing(klass: FirClass<*>) {
|
||||
delegate.endComputing(klass)
|
||||
}
|
||||
|
||||
override fun computeOnlyClassStatus(klass: FirClass<*>) {
|
||||
delegate.computeOnlyClassStatus(klass)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,8 +252,6 @@ abstract class AbstractFirStatusResolveTransformer(
|
||||
|
||||
protected val containingClass: FirClass<*>? get() = classes.lastOrNull()
|
||||
|
||||
private val symbolProvider = session.symbolProvider
|
||||
|
||||
protected abstract fun FirDeclaration.needResolveMembers(): Boolean
|
||||
protected abstract fun FirDeclaration.needResolveNestedClassifiers(): Boolean
|
||||
|
||||
@@ -353,64 +369,54 @@ abstract class AbstractFirStatusResolveTransformer(
|
||||
|
||||
protected fun forceResolveStatusesOfSupertypes(regularClass: FirRegularClass) {
|
||||
for (superTypeRef in regularClass.superTypeRefs) {
|
||||
forceResolveStatusOfCorrespondingClass(superTypeRef, regularClass)
|
||||
forceResolveStatusOfCorrespondingClass(superTypeRef)
|
||||
}
|
||||
}
|
||||
|
||||
private fun forceResolveStatusOfCorrespondingClass(typeRef: FirTypeRef, subClass: FirRegularClass?) {
|
||||
val classId = typeRef.coneType.classId ?: return
|
||||
val superClass = when {
|
||||
classId.isLocal -> {
|
||||
requireNotNull(subClass)
|
||||
var parent = designationMapForLocalClasses[subClass] as? FirRegularClass
|
||||
if (parent == null && scopeForLocalClass != null) {
|
||||
scopeForLocalClass.processClassifiersByName(classId.shortClassName) {
|
||||
if (it is FirRegularClass && it.classId == classId) {
|
||||
parent = it
|
||||
}
|
||||
}
|
||||
}
|
||||
parent
|
||||
}
|
||||
else -> symbolProvider.getClassLikeSymbolByFqName(classId)?.fir
|
||||
} ?: return
|
||||
when (superClass) {
|
||||
private fun forceResolveStatusOfCorrespondingClass(typeRef: FirTypeRef) {
|
||||
when (val superClass = typeRef.coneType.toSymbol(session)?.fir) {
|
||||
is FirRegularClass -> forceResolveStatusesOfClass(superClass)
|
||||
is FirTypeAlias -> forceResolveStatusOfCorrespondingClass(superClass.expandedTypeRef, subClass = null)
|
||||
is FirTypeAlias -> forceResolveStatusOfCorrespondingClass(superClass.expandedTypeRef)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private fun forceResolveStatusesOfClass(regularClass: FirRegularClass) {
|
||||
val firProvider = regularClass.session.firProvider
|
||||
if (statusComputationSession[regularClass] == StatusComputationSession.StatusComputationStatus.Computed) return
|
||||
val file = firProvider.getFirClassifierContainerFileIfAny(regularClass.symbol)
|
||||
if (regularClass.status is FirResolvedDeclarationStatus) {
|
||||
statusComputationSession.endComputing(regularClass)
|
||||
if (regularClass.origin == FirDeclarationOrigin.Java) {
|
||||
/*
|
||||
* If regular class has no corresponding file then it is platform class,
|
||||
* so we need to resolve supertypes of this class because they could
|
||||
* come from kotlin sources
|
||||
*/
|
||||
if (file == null) {
|
||||
forceResolveStatusesOfSupertypes(regularClass)
|
||||
}
|
||||
forceResolveStatusesOfSupertypes(regularClass)
|
||||
return
|
||||
}
|
||||
require(file != null) {
|
||||
"Containing file was not found for\n${regularClass.render()}"
|
||||
if (regularClass.resolvePhase > FirResolvePhase.STATUS) return
|
||||
val firProvider = regularClass.session.firProvider
|
||||
val statusComputationStatus = statusComputationSession[regularClass]
|
||||
if (!statusComputationStatus.requiresComputation) return
|
||||
|
||||
if (regularClass.status is FirResolvedDeclarationStatus && statusComputationStatus == StatusComputationSession.StatusComputationStatus.Computed) {
|
||||
statusComputationSession.endComputing(regularClass)
|
||||
return
|
||||
}
|
||||
val symbol = regularClass.symbol
|
||||
var declarationToStart: FirDeclaration? = null
|
||||
val designation = designationMapForLocalClasses[regularClass]?.let(::listOf)?.also {
|
||||
declarationToStart = it.first()
|
||||
} ?: buildList<FirDeclaration> {
|
||||
val designation = if (regularClass.isLocal) buildList {
|
||||
var klass: FirClassLikeDeclaration<*> = regularClass
|
||||
while (true) {
|
||||
this.add(klass)
|
||||
klass = designationMapForLocalClasses[klass]?.takeIf { it !is FirAnonymousObject } ?: break
|
||||
}
|
||||
reverse()
|
||||
} else buildList<FirDeclaration> {
|
||||
val outerClasses = generateSequence(symbol.classId) { classId ->
|
||||
classId.outerClassId
|
||||
}.mapTo(mutableListOf()) { firProvider.getFirClassifierByFqName(it) }
|
||||
declarationToStart = file
|
||||
val file = firProvider.getFirClassifierContainerFileIfAny(regularClass.symbol)
|
||||
requireNotNull(file) { "Containing file was not found for\n${regularClass.render()}" }
|
||||
this += outerClasses.filterNotNull().asReversed()
|
||||
}
|
||||
|
||||
if (designation.isEmpty()) return
|
||||
|
||||
val transformer = FirDesignatedStatusResolveTransformer(
|
||||
@@ -422,7 +428,7 @@ abstract class AbstractFirStatusResolveTransformer(
|
||||
designationMapForLocalClasses,
|
||||
scopeForLocalClass
|
||||
)
|
||||
declarationToStart!!.transformSingle(transformer, null)
|
||||
designation.first().transformSingle(transformer, null)
|
||||
statusComputationSession.endComputing(regularClass)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user