FIR checker: report AMBIGUOUS_SUPER

This commit is contained in:
Tianyu Geng
2021-07-19 15:13:39 -07:00
committed by Ivan Kochurkin
parent 5b9ce7e823
commit 06ee84f809
20 changed files with 59 additions and 27 deletions
@@ -15,7 +15,7 @@ open class B {
override fun foo() {
super.foo()
super.<!UNRESOLVED_REFERENCE!>bar<!>() // should be ambiguity (NB: really we should have overridden bar in C)
<!AMBIGUOUS_SUPER!>super<!>.bar() // should be ambiguity (NB: really we should have overridden bar in C)
super.baz() // Ok
baz() // Ok
@@ -178,6 +178,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<FirRegularClassSymbol>("type")
parameter<Collection<ConeKotlinType>>("bounds")
}
val AMBIGUOUS_SUPER by error<KtSuperExpression>()
}
val CONSTRUCTOR_PROBLEMS by object : DiagnosticGroup("Constructor problems") {
@@ -71,6 +71,7 @@ import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtPropertyAccessor
import org.jetbrains.kotlin.psi.KtReturnExpression
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.psi.KtSuperExpression
import org.jetbrains.kotlin.psi.KtTypeAlias
import org.jetbrains.kotlin.psi.KtTypeParameter
import org.jetbrains.kotlin.psi.KtTypeProjection
@@ -172,6 +173,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>()
// Constructor problems
val CONSTRUCTOR_IN_OBJECT by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
@@ -79,7 +79,10 @@ class ErrorNodeDiagnosticCollectorComponent(
private fun FirExpression?.cannotBeResolved(): Boolean {
return when (val diagnostic = (this?.typeRef as? FirErrorTypeRef)?.diagnostic) {
is ConeUnresolvedNameError, is ConeInstanceAccessBeforeSuperCall -> true
is ConeSimpleDiagnostic -> diagnostic.kind == DiagnosticKind.NotASupertype || diagnostic.kind == DiagnosticKind.SuperNotAvailable || diagnostic.kind == DiagnosticKind.UnresolvedLabel
is ConeSimpleDiagnostic -> diagnostic.kind == DiagnosticKind.NotASupertype ||
diagnostic.kind == DiagnosticKind.SuperNotAvailable ||
diagnostic.kind == DiagnosticKind.UnresolvedLabel ||
diagnostic.kind == DiagnosticKind.AmbiguousSuper
else -> false
}
}
@@ -51,6 +51,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_WITHOUT_EXPECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ACTUALS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_EXPECTS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_SUPER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_ARGUMENT_MUST_BE_CONST
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_CLASS_CONSTRUCTOR_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_CLASS_MEMBER
@@ -582,6 +583,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>'")
// Constructor problems
map.put(CONSTRUCTOR_IN_OBJECT, "Constructors are not allowed for objects")
@@ -372,6 +372,7 @@ 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
@@ -236,17 +236,19 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
}
else -> {
val types = components.findTypesForSuperCandidates(superTypeRefs, containingCall)
val resultType = if (types.size == 1) {
// NB: NOT_A_SUPERTYPE is reported by a separate checker
buildResolvedTypeRef {
val resultType = when (types.size) {
0 -> buildErrorTypeRef {
source = superReferenceContainer.source
// Report stub error so that it won't surface up. Instead, errors on the callee would be reported.
diagnostic = ConeStubDiagnostic(ConeSimpleDiagnostic("Unresolved super method", DiagnosticKind.Other))
}
1 -> buildResolvedTypeRef {
source = superReferenceContainer.source?.fakeElement(FirFakeSourceElementKind.SuperCallImplicitType)
type = types.single()
}
} else {
buildErrorTypeRef {
else -> buildErrorTypeRef {
source = superReferenceContainer.source
// NB: NOT_A_SUPERTYPE is reported by a separate checker
diagnostic = ConeStubDiagnostic(ConeSimpleDiagnostic("Ambiguous supertype", DiagnosticKind.Other))
diagnostic = ConeSimpleDiagnostic("Ambiguous supertype", DiagnosticKind.AmbiguousSuper)
}
}
superReferenceContainer.resultType =
@@ -48,6 +48,7 @@ enum class DiagnosticKind {
MissingStdlibClass,
NotASupertype,
SuperNotAvailable,
AmbiguousSuper,
LoopInSupertype,
RecursiveTypealiasExpansion,