[FIR] Fix resolution of calls on super to avoid resolve to interface methods
#KT-38400 Fixed
This commit is contained in:
+17
@@ -0,0 +1,17 @@
|
||||
// ISSUE: KT-38400
|
||||
|
||||
interface IWithToString {
|
||||
override fun toString(): String
|
||||
fun foo(): String
|
||||
fun bar(): String
|
||||
}
|
||||
|
||||
open class B {
|
||||
open fun foo(): String = ""
|
||||
}
|
||||
|
||||
class A : IWithToString, B() {
|
||||
override fun toString(): String = super.toString() // resolve to Any.toString
|
||||
override fun foo(): String = super.foo() // resolve to B.foo()
|
||||
override fun bar(): String = super.<!ABSTRACT_SUPER_CALL!>bar<!>() // should be an error
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
FILE: abstractSuperCallInPresenseOfNonAbstractMethodInParent.kt
|
||||
public abstract interface IWithToString : R|kotlin/Any| {
|
||||
public abstract override fun toString(): R|kotlin/String|
|
||||
|
||||
public abstract fun foo(): R|kotlin/String|
|
||||
|
||||
public abstract fun bar(): R|kotlin/String|
|
||||
|
||||
}
|
||||
public open class B : R|kotlin/Any| {
|
||||
public constructor(): R|B| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
public open fun foo(): R|kotlin/String| {
|
||||
^foo String()
|
||||
}
|
||||
|
||||
}
|
||||
public final class A : R|IWithToString|, R|B| {
|
||||
public constructor(): R|A| {
|
||||
super<R|B|>()
|
||||
}
|
||||
|
||||
public final override fun toString(): R|kotlin/String| {
|
||||
^toString this@R|/A|.super<R|B|>.R|kotlin/Any.toString|()
|
||||
}
|
||||
|
||||
public final override fun foo(): R|kotlin/String| {
|
||||
^foo this@R|/A|.super<R|B|>.R|/B.foo|()
|
||||
}
|
||||
|
||||
public final override fun bar(): R|kotlin/String| {
|
||||
^bar this@R|/A|.super<R|IWithToString|>.R|/IWithToString.bar|()
|
||||
}
|
||||
|
||||
}
|
||||
Generated
+5
@@ -937,6 +937,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/abstractSuperCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("abstractSuperCallInPresenseOfNonAbstractMethodInParent.kt")
|
||||
public void testAbstractSuperCallInPresenseOfNonAbstractMethodInParent() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/abstractSuperCallInPresenseOfNonAbstractMethodInParent.kt");
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDiagnostics() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/diagnostics"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
+5
@@ -937,6 +937,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/abstractSuperCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("abstractSuperCallInPresenseOfNonAbstractMethodInParent.kt")
|
||||
public void testAbstractSuperCallInPresenseOfNonAbstractMethodInParent() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/abstractSuperCallInPresenseOfNonAbstractMethodInParent.kt");
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDiagnostics() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/diagnostics"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
@@ -103,6 +104,13 @@ internal sealed class CheckReceivers : ResolutionStage() {
|
||||
val explicitReceiverExpression = callInfo.explicitReceiver
|
||||
val explicitReceiverKind = candidate.explicitReceiverKind
|
||||
|
||||
if (explicitReceiverExpression.isSuperCall()) {
|
||||
val status = candidate.symbol.fir as? FirMemberDeclaration
|
||||
if (status?.modality == Modality.ABSTRACT) {
|
||||
sink.reportDiagnostic(ResolvedWithLowPriority)
|
||||
}
|
||||
}
|
||||
|
||||
if (expectedReceiverType != null) {
|
||||
if (explicitReceiverExpression != null &&
|
||||
explicitReceiverKind.shouldBeCheckedAgainstExplicit() &&
|
||||
@@ -136,6 +144,11 @@ internal sealed class CheckReceivers : ResolutionStage() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirExpression?.isSuperCall(): Boolean {
|
||||
if (this !is FirQualifiedAccessExpression) return false
|
||||
return calleeReference is FirSuperReference
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirExpression.isSuperReferenceExpression(): Boolean {
|
||||
|
||||
Reference in New Issue
Block a user