Forbid usages of super if in fact it accesses an abstract member

#KT-49017 Fixed
This commit is contained in:
Mikhail Glukhikh
2022-01-10 14:19:19 +03:00
parent d15270b9e5
commit b689bbf5c7
23 changed files with 279 additions and 4 deletions
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.ContextReceiverAmbiguity
import org.jetbrains.kotlin.resolve.calls.tower.InfixCallNoInfixModifier
import org.jetbrains.kotlin.resolve.calls.tower.InvokeConventionCallNoOperatorModifier
import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
import org.jetbrains.kotlin.resolve.descriptorUtil.isInsideInterface
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf
@@ -809,8 +810,17 @@ internal object CheckSuperExpressionCallPart : ResolutionPart() {
val candidateDescriptor = resolvedCall.candidateDescriptor
if (callComponents.statelessCallbacks.isSuperExpression(resolvedCall.dispatchReceiverArgument)) {
if (candidateDescriptor is MemberDescriptor && candidateDescriptor.modality == Modality.ABSTRACT) {
addDiagnostic(AbstractSuperCall)
if (candidateDescriptor is CallableMemberDescriptor) {
if (candidateDescriptor.modality == Modality.ABSTRACT) {
addDiagnostic(AbstractSuperCall)
}
if (candidateDescriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
candidateDescriptor.overriddenDescriptors.size > 1
) {
if (candidateDescriptor.overriddenDescriptors.firstOrNull { !it.isInsideInterface }?.modality == Modality.ABSTRACT) {
addDiagnostic(AbstractFakeOverrideSuperCall)
}
}
}
}
@@ -208,6 +208,12 @@ object AbstractSuperCall : KotlinCallDiagnostic(RUNTIME_ERROR) {
}
}
object AbstractFakeOverrideSuperCall : KotlinCallDiagnostic(RUNTIME_ERROR) {
override fun report(reporter: DiagnosticReporter) {
reporter.onCall(this)
}
}
class SuperAsExtensionReceiver(val receiver: SimpleKotlinCallArgument) : KotlinCallDiagnostic(RUNTIME_ERROR) {
override fun report(reporter: DiagnosticReporter) {
reporter.onCallReceiver(receiver, this)