FIR IDE: pass candidate super types for AMBIGUOUS_SUPER
This way the IDE quickfix do not need to do resolution again to figure out what super type to offer in the quickfix.
This commit is contained in:
committed by
Ilya Kirillov
parent
7c3706dd3f
commit
bdc71a3281
+3
@@ -569,6 +569,9 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
||||
}
|
||||
add(FirErrors.AMBIGUOUS_SUPER) { firDiagnostic ->
|
||||
AmbiguousSuperImpl(
|
||||
firDiagnostic.a.map { coneKotlinType ->
|
||||
firSymbolBuilder.typeBuilder.buildKtType(coneKotlinType)
|
||||
},
|
||||
firDiagnostic as FirPsiDiagnostic,
|
||||
token,
|
||||
)
|
||||
|
||||
+1
@@ -425,6 +425,7 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
|
||||
abstract class AmbiguousSuper : KtFirDiagnostic<KtSuperExpression>() {
|
||||
override val diagnosticClass get() = AmbiguousSuper::class
|
||||
abstract val candidates: List<KtType>
|
||||
}
|
||||
|
||||
abstract class ConstructorInObject : KtFirDiagnostic<KtDeclaration>() {
|
||||
|
||||
+1
@@ -500,6 +500,7 @@ internal class InconsistentTypeParameterBoundsImpl(
|
||||
) : KtFirDiagnostic.InconsistentTypeParameterBounds(), KtAbstractFirDiagnostic<PsiElement>
|
||||
|
||||
internal class AmbiguousSuperImpl(
|
||||
override val candidates: List<KtType>,
|
||||
override val firDiagnostic: FirPsiDiagnostic,
|
||||
override val token: ValidityToken,
|
||||
) : KtFirDiagnostic.AmbiguousSuper(), KtAbstractFirDiagnostic<KtSuperExpression>
|
||||
|
||||
+3
-1
@@ -192,7 +192,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
parameter<FirRegularClassSymbol>("type")
|
||||
parameter<Collection<ConeKotlinType>>("bounds")
|
||||
}
|
||||
val AMBIGUOUS_SUPER by error<KtSuperExpression>()
|
||||
val AMBIGUOUS_SUPER by error<KtSuperExpression> {
|
||||
parameter<List<ConeKotlinType>>("candidates")
|
||||
}
|
||||
}
|
||||
|
||||
val CONSTRUCTOR_PROBLEMS by object : DiagnosticGroup("Constructor problems") {
|
||||
|
||||
+1
-1
@@ -183,7 +183,7 @@ object FirErrors {
|
||||
val PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE by error0<KtModifierListOwner>(SourceElementPositioningStrategies.VARIANCE_MODIFIER)
|
||||
val INCONSISTENT_TYPE_PARAMETER_VALUES by error3<KtClass, FirTypeParameterSymbol, FirRegularClassSymbol, Collection<ConeKotlinType>>(SourceElementPositioningStrategies.SUPERTYPES_LIST)
|
||||
val INCONSISTENT_TYPE_PARAMETER_BOUNDS by error3<PsiElement, FirTypeParameterSymbol, FirRegularClassSymbol, Collection<ConeKotlinType>>()
|
||||
val AMBIGUOUS_SUPER by error0<KtSuperExpression>()
|
||||
val AMBIGUOUS_SUPER by error1<KtSuperExpression, List<ConeKotlinType>>()
|
||||
|
||||
// Constructor problems
|
||||
val CONSTRUCTOR_IN_OBJECT by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||
|
||||
+3
-3
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.toFirDiagnostics
|
||||
import org.jetbrains.kotlin.fir.declarations.FirErrorFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirErrorImport
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeAmbiguousSuper
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
@@ -75,11 +76,10 @@ class ErrorNodeDiagnosticCollectorComponent(
|
||||
|
||||
private fun FirExpression?.cannotBeResolved(): Boolean {
|
||||
return when (val diagnostic = (this?.typeRef as? FirErrorTypeRef)?.diagnostic) {
|
||||
is ConeUnresolvedNameError, is ConeInstanceAccessBeforeSuperCall -> true
|
||||
is ConeUnresolvedNameError, is ConeInstanceAccessBeforeSuperCall, is ConeAmbiguousSuper -> true
|
||||
is ConeSimpleDiagnostic -> diagnostic.kind == DiagnosticKind.NotASupertype ||
|
||||
diagnostic.kind == DiagnosticKind.SuperNotAvailable ||
|
||||
diagnostic.kind == DiagnosticKind.UnresolvedLabel ||
|
||||
diagnostic.kind == DiagnosticKind.AmbiguousSuper
|
||||
diagnostic.kind == DiagnosticKind.UnresolvedLabel
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -636,7 +636,7 @@ class FirDefaultErrorMessages {
|
||||
SYMBOL,
|
||||
RENDER_COLLECTION_OF_TYPES
|
||||
)
|
||||
map.put(AMBIGUOUS_SUPER, "Many supertypes available, please specify the one you mean in angle brackets, e.g. 'super<Foo>'")
|
||||
map.put(AMBIGUOUS_SUPER, "Many supertypes available, please specify the one you mean in angle brackets, e.g. 'super<Foo>'", NOT_RENDERED)
|
||||
|
||||
// Constructor problems
|
||||
map.put(CONSTRUCTOR_IN_OBJECT, "Constructors are not allowed for objects")
|
||||
|
||||
+1
-1
@@ -111,6 +111,7 @@ private fun ConeDiagnostic.toFirDiagnostic(
|
||||
runIf(variable.isLocalMember) { FirErrors.VARIABLE_WITH_NO_TYPE_NO_INITIALIZER.createOn(source) }
|
||||
is ConeUnderscoreIsReserved -> FirErrors.UNDERSCORE_IS_RESERVED.createOn(this.source)
|
||||
is ConeUnderscoreUsageWithoutBackticks -> FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS.createOn(this.source)
|
||||
is ConeAmbiguousSuper -> FirErrors.AMBIGUOUS_SUPER.createOn(source, this.candidateTypes)
|
||||
else -> throw IllegalArgumentException("Unsupported diagnostic type: ${this.javaClass}")
|
||||
}
|
||||
|
||||
@@ -407,7 +408,6 @@ private fun ConeSimpleDiagnostic.getFactory(source: FirSourceElement): FirDiagno
|
||||
DiagnosticKind.EnumEntryAsType -> FirErrors.ENUM_ENTRY_AS_TYPE
|
||||
DiagnosticKind.NotASupertype -> FirErrors.NOT_A_SUPERTYPE
|
||||
DiagnosticKind.SuperNotAvailable -> FirErrors.SUPER_NOT_AVAILABLE
|
||||
DiagnosticKind.AmbiguousSuper -> FirErrors.AMBIGUOUS_SUPER
|
||||
DiagnosticKind.UnresolvedSupertype,
|
||||
DiagnosticKind.UnresolvedExpandedType,
|
||||
DiagnosticKind.Other -> FirErrors.OTHER_ERROR
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
fun BodyResolveComponents.findTypesForSuperCandidates(
|
||||
superTypeRefs: List<FirTypeRef>,
|
||||
containingCall: FirQualifiedAccess,
|
||||
): Collection<ConeKotlinType> {
|
||||
): List<ConeKotlinType> {
|
||||
val supertypes = superTypeRefs.map { (it as FirResolvedTypeRef).type }
|
||||
val isMethodOfAny = containingCall is FirFunctionCall && isCallingMethodOfAny(containingCall)
|
||||
if (supertypes.size <= 1 && !isMethodOfAny) return supertypes
|
||||
@@ -61,7 +61,7 @@ private fun isCallingMethodOfAny(callExpression: FirFunctionCall): Boolean =
|
||||
private fun BodyResolveComponents.resolveSupertypesForMethodOfAny(
|
||||
supertypes: Collection<ConeKotlinType>,
|
||||
calleeName: Name
|
||||
): Collection<ConeKotlinType> {
|
||||
): List<ConeKotlinType> {
|
||||
val typesWithConcreteOverride = resolveSupertypesByMembers(supertypes, false) {
|
||||
getFunctionMembers(it, calleeName)
|
||||
}
|
||||
@@ -71,13 +71,19 @@ private fun BodyResolveComponents.resolveSupertypesForMethodOfAny(
|
||||
listOf(session.builtinTypes.anyType.type)
|
||||
}
|
||||
|
||||
private fun BodyResolveComponents.resolveSupertypesByCalleeName(supertypes: Collection<ConeKotlinType>, calleeName: Name): Collection<ConeKotlinType> =
|
||||
private fun BodyResolveComponents.resolveSupertypesByCalleeName(
|
||||
supertypes: Collection<ConeKotlinType>,
|
||||
calleeName: Name
|
||||
): List<ConeKotlinType> =
|
||||
resolveSupertypesByMembers(supertypes, true) {
|
||||
getFunctionMembers(it, calleeName) +
|
||||
getPropertyMembers(it, calleeName)
|
||||
}
|
||||
|
||||
private fun BodyResolveComponents.resolveSupertypesByPropertyName(supertypes: Collection<ConeKotlinType>, propertyName: Name): Collection<ConeKotlinType> =
|
||||
private fun BodyResolveComponents.resolveSupertypesByPropertyName(
|
||||
supertypes: Collection<ConeKotlinType>,
|
||||
propertyName: Name
|
||||
): List<ConeKotlinType> =
|
||||
resolveSupertypesByMembers(supertypes, true) {
|
||||
getPropertyMembers(it, propertyName)
|
||||
}
|
||||
@@ -86,7 +92,7 @@ private inline fun BodyResolveComponents.resolveSupertypesByMembers(
|
||||
supertypes: Collection<ConeKotlinType>,
|
||||
allowNonConcreteMembers: Boolean,
|
||||
getMembers: (ConeKotlinType) -> Collection<FirCallableDeclaration>
|
||||
): Collection<ConeKotlinType> {
|
||||
): List<ConeKotlinType> {
|
||||
val typesWithConcreteMembers = SmartList<ConeKotlinType>()
|
||||
val typesWithNonConcreteMembers = SmartList<ConeKotlinType>()
|
||||
|
||||
|
||||
+2
-5
@@ -8,10 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildErrorExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
|
||||
@@ -266,7 +263,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
||||
}
|
||||
else -> buildErrorTypeRef {
|
||||
source = superReferenceContainer.source
|
||||
diagnostic = ConeSimpleDiagnostic("Ambiguous supertype", DiagnosticKind.AmbiguousSuper)
|
||||
diagnostic = ConeAmbiguousSuper(types)
|
||||
}
|
||||
}
|
||||
superReferenceContainer.resultType =
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.fir.diagnostics
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
|
||||
class ConeSimpleDiagnostic(override val reason: String, val kind: DiagnosticKind = DiagnosticKind.Other) : ConeDiagnostic
|
||||
|
||||
@@ -23,6 +24,11 @@ class ConeUnderscoreUsageWithoutBackticks(source: FirSourceElement) : ConeDiagno
|
||||
override val reason: String get() = "Names _, __, ___, ... can be used only in back-ticks (`_`, `__`, `___`, ...)"
|
||||
}
|
||||
|
||||
class ConeAmbiguousSuper(val candidateTypes: List<ConeKotlinType>) : ConeDiagnostic {
|
||||
override val reason: String
|
||||
get() = "Ambiguous supertype"
|
||||
}
|
||||
|
||||
enum class DiagnosticKind {
|
||||
Syntax,
|
||||
ExpressionExpected,
|
||||
@@ -49,7 +55,6 @@ enum class DiagnosticKind {
|
||||
MissingStdlibClass,
|
||||
NotASupertype,
|
||||
SuperNotAvailable,
|
||||
AmbiguousSuper,
|
||||
|
||||
LoopInSupertype,
|
||||
RecursiveTypealiasExpansion,
|
||||
|
||||
Reference in New Issue
Block a user