From db38cd95daf1458a4d38a2b8db5bd286a378bb94 Mon Sep 17 00:00:00 2001 From: Mark Punzalan Date: Thu, 19 Aug 2021 21:55:18 +0000 Subject: [PATCH] HL API: Add candidate symbols to KtClassErrorType. Also remove redundant FirReferenceResolveHelper.getFirSymbolsByErrorNamedReference() in favor of FirUtils.getCandidateSymbols(), and add more candidate symbols from more ConeDiagnostic subclasses. --- .../kotlin/idea/frontend/api/types/KtType.kt | 1 + .../org/jetbrains/kotlin/idea/fir/FirUtils.kt | 28 +++++++++++++------ .../frontend/api/fir/KtSymbolByFirBuilder.kt | 2 +- .../idea/frontend/api/fir/types/FirKtType.kt | 10 +++++++ .../idea/frontend/api/fir/utils/firUtils.kt | 3 +- .../references/FirReferenceResolveHelper.kt | 13 +-------- 6 files changed, 34 insertions(+), 23 deletions(-) diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/types/KtType.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/types/KtType.kt index 40ff0083878..e001e9137d5 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/types/KtType.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/types/KtType.kt @@ -50,6 +50,7 @@ public abstract class KtUsualClassType : KtNonErrorClassType() public abstract class KtClassErrorType : KtClassType() { public abstract val error: String + public abstract val candidateClassSymbols: Collection } public abstract class KtTypeParameterType : KtType { diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirUtils.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirUtils.kt index bc2ba419939..0b13303b9a8 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirUtils.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirUtils.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.idea.fir +import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.references.FirErrorNamedReference @@ -36,17 +37,26 @@ internal fun FirReference.getResolvedKtSymbolOfNameReference(builder: KtSymbolBy getResolvedSymbolOfNameReference()?.fir?.let(builder::buildSymbol) internal fun FirErrorNamedReference.getCandidateSymbols(): Collection> = - when (val diagnostic = diagnostic) { - is ConeInapplicableCandidateError -> listOf(diagnostic.candidate.symbol) - is ConeHiddenCandidateError -> listOf(diagnostic.candidateSymbol) - is ConeAmbiguityError -> diagnostic.candidates.map { it.symbol } - is ConeOperatorAmbiguityError -> diagnostic.candidates - is ConeUnsupportedCallableReferenceTarget -> listOf(diagnostic.fir.symbol) - else -> emptyList() - } + diagnostic.getCandidateSymbols() -internal fun FirNamedReference.getCandidateSymbols(): Collection> = when(this) { +internal fun FirNamedReference.getCandidateSymbols(): Collection> = when (this) { is FirResolvedNamedReference -> listOf(resolvedSymbol) is FirErrorNamedReference -> getCandidateSymbols() else -> emptyList() } + +internal fun ConeDiagnostic.getCandidateSymbols(): Collection> = + when (this) { + is ConeInapplicableCandidateError -> listOf(candidate.symbol) + is ConeHiddenCandidateError -> listOf(candidateSymbol) + is ConeAmbiguityError -> candidates.map { it.symbol } + is ConeOperatorAmbiguityError -> candidates + is ConeUnsupportedCallableReferenceTarget -> listOf(fir.symbol) + is ConeUnmatchedTypeArgumentsError -> listOf(symbol) + is ConeConstraintSystemHasContradiction -> listOf(candidate.symbol) + is ConeDeprecated -> listOf(symbol) + is ConeNoTypeArgumentsOnRhsError -> listOf(symbol) + is ConeResolutionToClassifierError -> listOf(classSymbol) + is ConeWrongNumberOfTypeArgumentsError -> listOf(symbol) + else -> emptyList() + } \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt index 1452f21bda5..bce671dc6fa 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt @@ -332,7 +332,7 @@ internal class KtSymbolByFirBuilder private constructor( else KtFirUsualClassType(coneType, token, this@KtSymbolByFirBuilder) } is ConeTypeParameterType -> KtFirTypeParameterType(coneType, token, this@KtSymbolByFirBuilder) - is ConeClassErrorType -> KtFirClassErrorType(coneType, token) + is ConeClassErrorType -> KtFirClassErrorType(coneType, token, this@KtSymbolByFirBuilder) is ConeFlexibleType -> KtFirFlexibleType(coneType, token, this@KtSymbolByFirBuilder) is ConeIntersectionType -> KtFirIntersectionType(coneType, token, this@KtSymbolByFirBuilder) is ConeDefinitelyNotNullType -> KtFirDefinitelyNotNullType(coneType, token, this@KtSymbolByFirBuilder) diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/types/FirKtType.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/types/FirKtType.kt index 93a7c1e76c8..579f5289e40 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/types/FirKtType.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/types/FirKtType.kt @@ -7,8 +7,10 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.types import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType import org.jetbrains.kotlin.fir.resolve.inference.receiverType +import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl +import org.jetbrains.kotlin.idea.fir.getCandidateSymbols import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgument import org.jetbrains.kotlin.idea.frontend.api.KtTypeArgumentWithVariance import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner @@ -116,11 +118,19 @@ internal class KtFirFunctionalType( internal class KtFirClassErrorType( _coneType: ConeClassErrorType, override val token: ValidityToken, + _builder: KtSymbolByFirBuilder, ) : KtClassErrorType(), KtFirType { override val coneType by weakRef(_coneType) + private val builder by weakRef(_builder) override val error: String get() = withValidityAssertion { coneType.diagnostic.reason } override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() } + + override val candidateClassSymbols: Collection by cached { + val symbols = coneType.diagnostic.getCandidateSymbols().filterIsInstance>() + symbols.map { builder.classifierBuilder.buildClassLikeSymbol(it.fir) } + } + override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() } override fun equals(other: Any?) = typeEquals(other) override fun hashCode() = typeHashcode() diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/firUtils.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/firUtils.kt index 337fa20b70b..36d3fdc62d9 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/firUtils.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/firUtils.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState import org.jetbrains.kotlin.idea.fir.low.level.api.api.withFirDeclaration import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.ResolveType +import org.jetbrains.kotlin.idea.fir.getCandidateSymbols import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtConstantValue import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSimpleConstantValue import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtUnsupportedConstantValue @@ -49,7 +50,7 @@ internal fun KtExpression.unwrap(): KtExpression { internal fun FirNamedReference.getReferencedElementType(resolveState: FirModuleResolveState): ConeKotlinType { val symbols = when (this) { is FirResolvedNamedReference -> listOf(resolvedSymbol) - is FirErrorNamedReference -> FirReferenceResolveHelper.getFirSymbolsByErrorNamedReference(this) + is FirErrorNamedReference -> getCandidateSymbols() else -> error("Unexpected ${this::class}") } val firCallableDeclaration = symbols.singleOrNull()?.fir as? FirCallableDeclaration diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt index 1d640e5dd3b..e74f5ec214a 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt @@ -312,18 +312,7 @@ internal object FirReferenceResolveHelper { fir: FirErrorNamedReference, symbolBuilder: KtSymbolByFirBuilder ): List = - getFirSymbolsByErrorNamedReference(fir).map { it.fir.buildSymbol(symbolBuilder) } - - - fun getFirSymbolsByErrorNamedReference( - errorNamedReference: FirErrorNamedReference, - ): Collection> = when (val diagnostic = errorNamedReference.diagnostic) { - is ConeAmbiguityError -> diagnostic.candidates.map { it.symbol } - is ConeOperatorAmbiguityError -> diagnostic.candidates - is ConeInapplicableCandidateError -> listOf(diagnostic.candidate.symbol) - else -> emptyList() - } - + fir.getCandidateSymbols().map { it.fir.buildSymbol(symbolBuilder) } private fun getSymbolsByReturnExpression( expression: KtSimpleNameExpression,