[Analysis API] separate non-class error types from class error types and add information about type qualifiers

it's needed for type printing in renderer
This commit is contained in:
Ilya Kirillov
2022-10-14 15:35:03 +02:00
parent 210212c284
commit 725ae1fc65
35 changed files with 510 additions and 83 deletions
@@ -76,4 +76,4 @@ internal fun FirAnnotation.toKtAnnotationApplication(useSiteSession: FirSession)
useSiteSession,
)
)
}
}
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withConeTypeEntry
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirEntry
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.withFirSymbolEntry
import org.jetbrains.kotlin.analysis.providers.createPackageProvider
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
@@ -34,6 +35,8 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferParameterType
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
import org.jetbrains.kotlin.fir.renderer.FirRenderer
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnmatchedTypeArgumentsError
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedError
import org.jetbrains.kotlin.fir.resolve.getContainingClass
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable
@@ -45,15 +48,14 @@ import org.jetbrains.kotlin.fir.scopes.impl.toConeType
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
@@ -446,7 +448,11 @@ internal class KtSymbolByFirBuilder constructor(
else KtFirUsualClassType(coneType, token, this@KtSymbolByFirBuilder)
}
is ConeTypeParameterType -> KtFirTypeParameterType(coneType, token, this@KtSymbolByFirBuilder)
is ConeErrorType -> KtFirClassErrorType(coneType, token, this@KtSymbolByFirBuilder)
is ConeErrorType -> when (val diagnostic = coneType.diagnostic) {
is ConeUnresolvedError, is ConeUnmatchedTypeArgumentsError ->
KtFirClassErrorType(coneType, diagnostic, token, this@KtSymbolByFirBuilder)
else -> KtFirTypeErrorType(coneType, token, this@KtSymbolByFirBuilder)
}
is ConeDynamicType -> KtFirDynamicType(coneType, token, this@KtSymbolByFirBuilder)
is ConeFlexibleType -> KtFirFlexibleType(coneType, token, this@KtSymbolByFirBuilder)
is ConeIntersectionType -> KtFirIntersectionType(coneType, token, this@KtSymbolByFirBuilder)
@@ -483,8 +489,8 @@ internal class KtSymbolByFirBuilder constructor(
return buildKtType(coneType.coneType)
}
fun buildTypeArgument(coneType: ConeTypeProjection): KtTypeArgument = when (coneType) {
is ConeStarProjection -> KtStarProjectionTypeArgument(token)
fun buildTypeProjection(coneType: ConeTypeProjection): KtTypeProjection = when (coneType) {
is ConeStarProjection -> KtStarTypeProjection(token)
is ConeKotlinTypeProjection -> KtTypeArgumentWithVariance(
buildKtType(coneType.type),
coneType.kind.toVariance(),
@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.analysis.api.fir.components
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.analysis.api.KtStarProjectionTypeArgument
import org.jetbrains.kotlin.analysis.api.KtTypeArgument
import org.jetbrains.kotlin.analysis.api.KtStarTypeProjection
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnosticWithPsi
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
@@ -66,9 +65,9 @@ internal interface KtFirAnalysisSessionComponent {
return coneType
}
val KtTypeArgument.coneTypeProjection: ConeTypeProjection
val KtTypeProjection.coneTypeProjection: ConeTypeProjection
get() = when (this) {
is KtStarProjectionTypeArgument -> ConeStarProjection
is KtStarTypeProjection -> ConeStarProjection
is KtTypeArgumentWithVariance -> {
typeContext.createTypeArgument(type.coneType, variance.convertVariance()) as ConeTypeProjection
}
@@ -100,7 +100,7 @@ internal class ConeTypeIdeRenderer(
if (options.renderUnresolvedTypeAsResolved) {
when (diagnostic) {
is ConeUnresolvedError -> {
val qualifierRendered = diagnostic.qualifier?.let { FqName(it).render() }.orEmpty()
val qualifierRendered = diagnostic.qualifier.let { FqName(it).render() }
append(qualifierRendered)
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.api.fir.types
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForType
@@ -23,6 +24,9 @@ internal class KtFirCapturedType(
) : KtCapturedType(), KtFirType {
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
override val projection: KtTypeProjection
get() = withValidityAssertion { builder.typeBuilder.buildTypeProjection(coneType.constructor.projection) }
override val annotationsList: KtAnnotationsList by cached {
KtFirAnnotationListForType.create(coneType, builder.rootSession, token)
}
@@ -9,29 +9,47 @@ import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForType
import org.jetbrains.kotlin.analysis.api.fir.getCandidateSymbols
import org.jetbrains.kotlin.analysis.api.fir.types.qualifiers.ErrorClassTypeQualifierBuilder
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.types.KtClassErrorType
import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnmatchedTypeArgumentsError
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedError
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.renderForDebugging
internal class KtFirClassErrorType(
override val coneType: ConeErrorType,
private val coneDiagnostic: ConeDiagnostic,
override val token: KtLifetimeToken,
private val builder: KtSymbolByFirBuilder,
) : KtClassErrorType(), KtFirType {
override val error: String get() = withValidityAssertion { coneType.diagnostic.reason }
override val qualifiers: List<KtClassTypeQualifier> by cached {
when (coneDiagnostic) {
is ConeUnresolvedError ->
ErrorClassTypeQualifierBuilder.createQualifiersForUnresolvedType(coneDiagnostic, builder)
is ConeUnmatchedTypeArgumentsError ->
ErrorClassTypeQualifierBuilder.createQualifiersForUnmatchedTypeArgumentsType(coneDiagnostic, builder)
else -> error("Unsupported ${coneDiagnostic::class}")
}
}
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
override val errorMessage: String get() = withValidityAssertion { coneType.diagnostic.reason }
override val annotationsList: KtAnnotationsList by cached {
KtFirAnnotationListForType.create(coneType, builder.rootSession, token)
}
override val candidateClassSymbols: Collection<KtClassLikeSymbol> by cached {
val symbols = coneType.diagnostic.getCandidateSymbols().filterIsInstance<FirClassLikeSymbol<*>>()
symbols.map { builder.classifierBuilder.buildClassLikeSymbol(it) }
@@ -5,15 +5,17 @@
package org.jetbrains.kotlin.analysis.api.fir.types
import org.jetbrains.kotlin.analysis.api.KtTypeArgument
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForType
import org.jetbrains.kotlin.analysis.api.fir.types.qualifiers.UsualClassTypeQualifierBuilder
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier
import org.jetbrains.kotlin.analysis.api.types.KtFunctionalType
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
@@ -35,10 +37,10 @@ internal class KtFirFunctionalType(
builder.classifierBuilder.buildClassLikeSymbolByLookupTag(coneType.lookupTag)
?: errorWithFirSpecificEntries("Class was not found", coneType = coneType)
}
override val typeArguments: List<KtTypeArgument> by cached {
coneType.typeArguments.map { typeArgument ->
builder.typeBuilder.buildTypeArgument(typeArgument)
}
override val ownTypeArguments: List<KtTypeProjection> get() = withValidityAssertion { qualifiers.last().typeArguments }
override val qualifiers: List<KtClassTypeQualifier.KtResolvedClassTypeQualifier> by cached {
UsualClassTypeQualifierBuilder.buildQualifiers(coneType, builder)
}
override val annotationsList: KtAnnotationsList by cached {
@@ -56,7 +58,7 @@ internal class KtFirFunctionalType(
override val receiverType: KtType?
get() = withValidityAssertion {
if (coneType.isExtensionFunctionType) (typeArguments.first() as KtTypeArgumentWithVariance).type
if (coneType.isExtensionFunctionType) (ownTypeArguments.first() as KtTypeArgumentWithVariance).type
else null
}
@@ -66,13 +68,13 @@ internal class KtFirFunctionalType(
}
override val parameterTypes: List<KtType> by cached {
val parameterTypeArgs = if (coneType.isExtensionFunctionType) typeArguments.subList(1, typeArguments.lastIndex)
else typeArguments.subList(0, typeArguments.lastIndex)
val parameterTypeArgs = if (coneType.isExtensionFunctionType) ownTypeArguments.subList(1, ownTypeArguments.lastIndex)
else ownTypeArguments.subList(0, ownTypeArguments.lastIndex)
parameterTypeArgs.map { (it as KtTypeArgumentWithVariance).type }
}
override val returnType: KtType
get() = withValidityAssertion { (typeArguments.last() as KtTypeArgumentWithVariance).type }
get() = withValidityAssertion { (ownTypeArguments.last() as KtTypeArgumentWithVariance).type }
override fun asStringForDebugging(): String = withValidityAssertion { coneType.renderForDebugging() }
override fun equals(other: Any?) = typeEquals(other)
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2022 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.api.fir.types
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForType
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.types.KtTypeErrorType
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferParameterType
import org.jetbrains.kotlin.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.renderForDebugging
internal class KtFirTypeErrorType(
override val coneType: ConeErrorType,
override val token: KtLifetimeToken,
private val builder: KtSymbolByFirBuilder,
) : KtTypeErrorType(), KtFirType {
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
override val errorMessage: String get() = withValidityAssertion { coneType.diagnostic.reason }
override fun tryRenderAsNonErrorType(): String? = withValidityAssertion {
when (val diagnostic = coneType.diagnostic) {
is ConeCannotInferParameterType -> diagnostic.typeParameter.name.asString()
else -> null
}
}
override val annotationsList: KtAnnotationsList by cached {
KtFirAnnotationListForType.create(coneType, builder.rootSession, token)
}
override fun asStringForDebugging(): String = withValidityAssertion { coneType.renderForDebugging() }
override fun equals(other: Any?) = typeEquals(other)
override fun hashCode() = typeHashcode()
}
@@ -5,10 +5,11 @@
package org.jetbrains.kotlin.analysis.api.fir.types
import org.jetbrains.kotlin.analysis.api.KtTypeArgument
import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationsList
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForType
import org.jetbrains.kotlin.analysis.api.fir.types.qualifiers.UsualClassTypeQualifierBuilder
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
@@ -30,12 +31,13 @@ internal class KtFirUsualClassType(
builder.classifierBuilder.buildClassLikeSymbolByLookupTag(coneType.lookupTag)
?: errorWithFirSpecificEntries("Class was not found", coneType = coneType)
}
override val typeArguments: List<KtTypeArgument> by cached {
coneType.typeArguments.map { typeArgument ->
builder.typeBuilder.buildTypeArgument(typeArgument)
}
override val qualifiers by cached {
UsualClassTypeQualifierBuilder.buildQualifiers(coneType, builder)
}
override val ownTypeArguments: List<KtTypeProjection> get() = withValidityAssertion { qualifiers.last().typeArguments }
override val annotationsList: KtAnnotationsList by cached {
KtFirAnnotationListForType.create(coneType, builder.rootSession, token)
}
@@ -45,3 +47,4 @@ internal class KtFirUsualClassType(
override fun equals(other: Any?) = typeEquals(other)
override fun hashCode() = typeHashcode()
}
@@ -0,0 +1,64 @@
/*
* Copyright 2010-2022 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.api.fir.types.qualifiers
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.types.toConeTypeProjection
internal object ErrorClassTypeQualifierBuilder {
fun createQualifiersForUnresolvedType(
coneDiagnostic: ConeUnresolvedError,
builder: KtSymbolByFirBuilder
): List<KtClassTypeQualifier> {
return when (coneDiagnostic) {
is ConeUnresolvedTypeQualifierError ->
coneDiagnostic.qualifiers.map { part ->
KtClassTypeQualifier.KtUnresolvedClassTypeQualifier(
part.name,
part.typeArgumentList.typeArguments.map { builder.typeBuilder.buildTypeProjection(it.toConeTypeProjection()) },
builder.token
)
}
is ConeUnresolvedNameError -> listOf(
KtClassTypeQualifier.KtUnresolvedClassTypeQualifier(coneDiagnostic.name, emptyList(), builder.token)
)
is ConeUnresolvedReferenceError -> listOf(
KtClassTypeQualifier.KtUnresolvedClassTypeQualifier(coneDiagnostic.name, emptyList(), builder.token)
)
is ConeUnresolvedSymbolError ->
coneDiagnostic.classId.asSingleFqName().pathSegments()
.map { KtClassTypeQualifier.KtUnresolvedClassTypeQualifier(it, emptyList(), builder.token) }
}
}
fun createQualifiersForUnmatchedTypeArgumentsType(
coneDiagnostic: ConeUnmatchedTypeArgumentsError,
builder: KtSymbolByFirBuilder
): List<KtClassTypeQualifier> {
return createQualifiersByClassSymbol(coneDiagnostic.symbol, builder)
}
private fun createQualifiersByClassSymbol(
firSymbol: FirClassLikeSymbol<*>,
builder: KtSymbolByFirBuilder
): List<KtClassTypeQualifier.KtResolvedClassTypeQualifier> {
return generateSequence(firSymbol) { firSymbol.getContainingClassSymbol(builder.rootSession) }.mapTo(mutableListOf()) { classSymbol ->
KtClassTypeQualifier.KtResolvedClassTypeQualifier(
builder.classifierBuilder.buildClassLikeSymbol(classSymbol),
emptyList(),
builder.token
)
}
}
}
@@ -0,0 +1,115 @@
/*
* Copyright 2010-2022 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.api.fir.types.qualifiers
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.tryCollectDesignation
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.errorWithFirSpecificEntries
import org.jetbrains.kotlin.fir.containingClassForLocal
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.renderWithType
import org.jetbrains.kotlin.fir.resolve.getContainingClass
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.LookupTagInternals
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
internal object UsualClassTypeQualifierBuilder {
fun buildQualifiers(
coneType: ConeClassLikeTypeImpl,
builder: KtSymbolByFirBuilder
): List<KtClassTypeQualifier.KtResolvedClassTypeQualifier> {
val classSymbolToRender = coneType.lookupTag.toSymbol(builder.rootSession)
?: errorWithFirSpecificEntries("ConeClassLikeTypeImpl is not resolved to symbol for on-error type", coneType = coneType) {
withEntry("useSiteSession", builder.rootSession) { it.toString() }
}
if (classSymbolToRender !is FirRegularClassSymbol) {
return listOf(
KtClassTypeQualifier.KtResolvedClassTypeQualifier(
builder.classifierBuilder.buildClassifierSymbol(classSymbolToRender),
coneType.typeArguments.map { builder.typeBuilder.buildTypeProjection(it) },
builder.token
)
)
}
val designation = classSymbolToRender.fir.let {
val nonLocalDesignation = it.tryCollectDesignation()
nonLocalDesignation?.toSequence(includeTarget = true)?.toList()
?: collectDesignationPathForLocal(it)
?: emptyList()
}
var typeParametersLeft = coneType.typeArguments.size
fun needToRenderTypeParameters(index: Int): Boolean {
if (typeParametersLeft <= 0) return false
return index == designation.lastIndex ||
(designation[index] as? FirRegularClass)?.isInner == true ||
(designation[index + 1] as? FirRegularClass)?.isInner == true
}
val result = mutableListOf<KtClassTypeQualifier.KtResolvedClassTypeQualifier>()
designation.forEachIndexed { index, currentClass ->
check(currentClass is FirRegularClass)
val typeParameters = if (needToRenderTypeParameters(index)) {
val typeParametersCount = currentClass.typeParameters.count { it is FirTypeParameter }
val begin = typeParametersLeft - typeParametersCount
val end = typeParametersLeft
check(begin >= 0)
typeParametersLeft -= typeParametersCount
coneType.typeArguments.slice(begin until end).map { builder.typeBuilder.buildTypeProjection(it) }
} else emptyList()
result += KtClassTypeQualifier.KtResolvedClassTypeQualifier(
builder.classifierBuilder.buildClassifierSymbol(currentClass.symbol),
typeParameters,
builder.token
)
}
return result
}
private fun FirRegularClass.collectForLocal(): List<FirClassLikeDeclaration> {
require(isLocal)
var containingClassLookUp = containingClassForLocal()
val designation = mutableListOf<FirClassLikeDeclaration>(this)
@OptIn(LookupTagInternals::class)
while (containingClassLookUp != null && containingClassLookUp.classId.isLocal) {
val currentClass = containingClassLookUp.toFirRegularClass(moduleData.session) ?: break
designation.add(currentClass)
containingClassLookUp = currentClass.containingClassForLocal()
}
return designation
}
private fun collectDesignationPathForLocal(declaration: FirDeclaration): List<FirDeclaration>? {
@OptIn(LookupTagInternals::class)
val containingClass = when (declaration) {
is FirCallableDeclaration -> declaration.getContainingClass(declaration.moduleData.session)
is FirAnonymousObject -> return listOf(declaration)
is FirClassLikeDeclaration -> declaration.let {
if (!declaration.isLocal) return null
(it as? FirRegularClass)?.containingClassForLocal()?.toFirRegularClass(declaration.moduleData.session)
}
else -> error("Invalid declaration ${declaration.renderWithType()}")
} ?: return listOf(declaration)
return if (containingClass.isLocal) {
containingClass.collectForLocal().reversed()
} else {
null
}
}
}