diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index 3b04713247d..5993e39f11e 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -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, ) diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index d8a08adfb6b..2f10a464a8f 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -425,6 +425,7 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract class AmbiguousSuper : KtFirDiagnostic() { override val diagnosticClass get() = AmbiguousSuper::class + abstract val candidates: List } abstract class ConstructorInObject : KtFirDiagnostic() { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index bb5263d876d..99dce0274d9 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -500,6 +500,7 @@ internal class InconsistentTypeParameterBoundsImpl( ) : KtFirDiagnostic.InconsistentTypeParameterBounds(), KtAbstractFirDiagnostic internal class AmbiguousSuperImpl( + override val candidates: List, override val firDiagnostic: FirPsiDiagnostic, override val token: ValidityToken, ) : KtFirDiagnostic.AmbiguousSuper(), KtAbstractFirDiagnostic diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index b529cc5df53..d03be3d0b48 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -192,7 +192,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { parameter("type") parameter>("bounds") } - val AMBIGUOUS_SUPER by error() + val AMBIGUOUS_SUPER by error { + parameter>("candidates") + } } val CONSTRUCTOR_PROBLEMS by object : DiagnosticGroup("Constructor problems") { diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index c303a132eb5..89a87e80c78 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -183,7 +183,7 @@ object FirErrors { val PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE by error0(SourceElementPositioningStrategies.VARIANCE_MODIFIER) val INCONSISTENT_TYPE_PARAMETER_VALUES by error3>(SourceElementPositioningStrategies.SUPERTYPES_LIST) val INCONSISTENT_TYPE_PARAMETER_BOUNDS by error3>() - val AMBIGUOUS_SUPER by error0() + val AMBIGUOUS_SUPER by error1>() // Constructor problems val CONSTRUCTOR_IN_OBJECT by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt index 7013b841eb0..7c34c5d2625 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt @@ -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 } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 2238f6027ed..7f25082d3fc 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -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'") + map.put(AMBIGUOUS_SUPER, "Many supertypes available, please specify the one you mean in angle brackets, e.g. 'super'", NOT_RENDERED) // Constructor problems map.put(CONSTRUCTOR_IN_OBJECT, "Constructors are not allowed for objects") diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index e7d3b8e3223..f24f00e2813 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -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 diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/SuperCalls.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/SuperCalls.kt index d5d8ef632ed..912cd9a022c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/SuperCalls.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/SuperCalls.kt @@ -30,7 +30,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull fun BodyResolveComponents.findTypesForSuperCandidates( superTypeRefs: List, containingCall: FirQualifiedAccess, -): Collection { +): List { 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, calleeName: Name -): Collection { +): List { 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, calleeName: Name): Collection = +private fun BodyResolveComponents.resolveSupertypesByCalleeName( + supertypes: Collection, + calleeName: Name +): List = resolveSupertypesByMembers(supertypes, true) { getFunctionMembers(it, calleeName) + getPropertyMembers(it, calleeName) } -private fun BodyResolveComponents.resolveSupertypesByPropertyName(supertypes: Collection, propertyName: Name): Collection = +private fun BodyResolveComponents.resolveSupertypesByPropertyName( + supertypes: Collection, + propertyName: Name +): List = resolveSupertypesByMembers(supertypes, true) { getPropertyMembers(it, propertyName) } @@ -86,7 +92,7 @@ private inline fun BodyResolveComponents.resolveSupertypesByMembers( supertypes: Collection, allowNonConcreteMembers: Boolean, getMembers: (ConeKotlinType) -> Collection -): Collection { +): List { val typesWithConcreteMembers = SmartList() val typesWithNonConcreteMembers = SmartList() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 08304ec1746..3973947c395 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -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 = diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt index f48161d2c9d..00676a25e2d 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt @@ -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) : 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,