[FIR] Fix overloading of renamed jvm methods

#KT-48102 Fixed
This commit is contained in:
Andrey Zinovyev
2021-08-06 14:11:40 +03:00
committed by TeamCityServer
parent cd99c35649
commit 1b81018b69
14 changed files with 86 additions and 93 deletions
@@ -7495,6 +7495,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.kt"); runTest("compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.kt");
} }
@Test
@TestMetadata("mappedFunctionNotImplemented.kt")
public void testMappedFunctionNotImplemented() throws Exception {
runTest("compiler/testData/diagnostics/tests/declarationChecks/mappedFunctionNotImplemented.kt");
}
@Test @Test
@TestMetadata("mulitpleVarargParameters.kt") @TestMetadata("mulitpleVarargParameters.kt")
public void testMulitpleVarargParameters() throws Exception { public void testMulitpleVarargParameters() throws Exception {
@@ -7495,6 +7495,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.kt"); runTest("compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.kt");
} }
@Test
@TestMetadata("mappedFunctionNotImplemented.kt")
public void testMappedFunctionNotImplemented() throws Exception {
runTest("compiler/testData/diagnostics/tests/declarationChecks/mappedFunctionNotImplemented.kt");
}
@Test @Test
@TestMetadata("mulitpleVarargParameters.kt") @TestMetadata("mulitpleVarargParameters.kt")
public void testMulitpleVarargParameters() throws Exception { public void testMulitpleVarargParameters() throws Exception {
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.utils.isInterface import org.jetbrains.kotlin.fir.declarations.utils.isInterface
import org.jetbrains.kotlin.fir.declarations.utils.isOperator
import org.jetbrains.kotlin.fir.declarations.utils.modality import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
@@ -299,6 +300,13 @@ class JavaClassUseSiteMemberScope(
): FirNamedFunctionSymbol? { ): FirNamedFunctionSymbol? {
val overriddenBuiltin = symbol.getOverriddenBuiltinWithDifferentJvmName() ?: return null val overriddenBuiltin = symbol.getOverriddenBuiltinWithDifferentJvmName() ?: return null
//if (unrelated) method with special name is already defined, we don't add renamed method at all
//otherwise we get methods ambiguity
val alreadyDefined = declaredMemberScope.getFunctions(name).any { declaredSymbol ->
overrideChecker.isOverriddenFunction(declaredSymbol.fir, symbol.fir)
}
if (alreadyDefined) return null
val nameInJava = val nameInJava =
SpecialGenericSignatures.SIGNATURE_TO_JVM_REPRESENTATION_NAME[overriddenBuiltin.fir.computeJvmSignature() ?: return null] SpecialGenericSignatures.SIGNATURE_TO_JVM_REPRESENTATION_NAME[overriddenBuiltin.fir.computeJvmSignature() ?: return null]
?: return null ?: return null
@@ -308,6 +316,7 @@ class JavaClassUseSiteMemberScope(
val renamedCopy = buildJavaMethodCopy(candidateFir) { val renamedCopy = buildJavaMethodCopy(candidateFir) {
this.name = name this.name = name
this.symbol = FirNamedFunctionSymbol(CallableId(candidateFir.symbol.callableId.classId!!, name)) this.symbol = FirNamedFunctionSymbol(CallableId(candidateFir.symbol.callableId.classId!!, name))
this.status = candidateFir.status.copy(isOperator = symbol.isOperator)
}.apply { }.apply {
initialSignatureAttr = candidateFir initialSignatureAttr = candidateFir
} }
@@ -415,6 +424,10 @@ class JavaClassUseSiteMemberScope(
private fun FirNamedFunctionSymbol.getOverriddenBuiltinWithDifferentJvmName(): FirNamedFunctionSymbol? { private fun FirNamedFunctionSymbol.getOverriddenBuiltinWithDifferentJvmName(): FirNamedFunctionSymbol? {
var result: FirNamedFunctionSymbol? = null var result: FirNamedFunctionSymbol? = null
if (SpecialGenericSignatures.SIGNATURE_TO_JVM_REPRESENTATION_NAME.containsKey(this.fir.computeJvmSignature())) {
return this
}
superTypesScope.processOverriddenFunctions(this) { superTypesScope.processOverriddenFunctions(this) {
if (!it.isFromBuiltInClass(session)) return@processOverriddenFunctions ProcessorAction.NEXT if (!it.isFromBuiltInClass(session)) return@processOverriddenFunctions ProcessorAction.NEXT
if (SpecialGenericSignatures.SIGNATURE_TO_JVM_REPRESENTATION_NAME.containsKey(it.fir.computeJvmSignature())) { if (SpecialGenericSignatures.SIGNATURE_TO_JVM_REPRESENTATION_NAME.containsKey(it.fir.computeJvmSignature())) {
@@ -179,9 +179,10 @@ fun FirDeclarationStatus.copy(
isExpect: Boolean = this.isExpect, isExpect: Boolean = this.isExpect,
newModality: Modality? = null, newModality: Modality? = null,
newVisibility: Visibility? = null, newVisibility: Visibility? = null,
newEffectiveVisibility: EffectiveVisibility? = null newEffectiveVisibility: EffectiveVisibility? = null,
isOperator: Boolean = this.isOperator
): FirDeclarationStatus { ): FirDeclarationStatus {
return if (this.isExpect == isExpect && newModality == null && newVisibility == null) { return if (this.isExpect == isExpect && newModality == null && newVisibility == null && this.isOperator == isOperator) {
this this
} else { } else {
require(this is FirDeclarationStatusImpl) { "Unexpected class ${this::class}" } require(this is FirDeclarationStatusImpl) { "Unexpected class ${this::class}" }
@@ -191,6 +192,7 @@ fun FirDeclarationStatus.copy(
newEffectiveVisibility ?: EffectiveVisibility.Public newEffectiveVisibility ?: EffectiveVisibility.Public
).apply { ).apply {
this.isExpect = isExpect this.isExpect = isExpect
this.isOperator = isOperator
} }
} }
} }
@@ -0,0 +1,13 @@
// KT-48102
// FIR_IDENTICAL
// FILE: MyCharSequence.java
public class MyCharSequence implements CharSequence {
public char charAt(int index) { return ' '; }
public int length() { return 1; }
public CharSequence subSequence(int start, int end) { return this; }
public String toString() { return " "; }
}
// FILE: CharSeq.kt
class KtCharSeq : MyCharSequence() // false-positive 'get' not implemented
@@ -0,0 +1,21 @@
package
public final class KtCharSeq : MyCharSequence {
public constructor KtCharSeq()
public open override /*1*/ /*fake_override*/ val length: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.Char
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun subSequence(/*0*/ startIndex: kotlin.Int, /*1*/ endIndex: kotlin.Int): kotlin.CharSequence
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class MyCharSequence : kotlin.CharSequence {
public constructor MyCharSequence()
public open override /*1*/ val length: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ fun get(/*0*/ index: kotlin.Int): kotlin.Char
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ fun subSequence(/*0*/ startIndex: kotlin.Int, /*1*/ endIndex: kotlin.Int): kotlin.CharSequence
public open override /*1*/ fun toString(): kotlin.String
}
@@ -150,14 +150,14 @@ class Y2 : X() {
fun main() { fun main() {
X().remove("") X().remove("")
X().<!OVERLOAD_RESOLUTION_AMBIGUITY!>removeAt<!>(1) X().removeAt(1)
val y: MutableList<String> = Y() val y: MutableList<String> = Y()
y.removeAt(1) y.removeAt(1)
Y().remove("") Y().remove("")
Y().<!OVERLOAD_RESOLUTION_AMBIGUITY!>removeAt<!>(1) Y().removeAt(1)
X().remove("") X().remove("")
X().<!OVERLOAD_RESOLUTION_AMBIGUITY!>removeAt<!>(1) X().removeAt(1)
} }
@@ -1,32 +0,0 @@
// JAVAC_EXPECTED_FILE
// FILE: A.java
abstract public class A extends B {
public Integer removeAt(int x) { }
public boolean remove(Integer x) { }
}
// FILE: main.kt
import java.util.*;
abstract class B : MutableList<Int>, AbstractList<Int>() {
override fun removeAt(index: Int): Int = null!!
override fun remove(element: Int): Boolean = null!!
}
abstract class D : AbstractList<Int>() {
// removeAt() doesn't exist in java/util/AbstractList, it's a
// fake override of the method from kotlin/collections/MutableList
override fun removeAt(index: Int): Int = null!!
// AbstractList::remove() should return Int here. No fake overrides created.
// This may be a bug because the old compiler doesn't report a diagnostic here.
override fun remove(element: Int): Boolean = null!!
}
fun main(a: A, b: B, c: ArrayList<Int>) {
a.remove(1)
a.<!OVERLOAD_RESOLUTION_AMBIGUITY!>removeAt<!>(0)
b.remove(1)
b.removeAt(0)
c.remove(1)
c.removeAt(0)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// JAVAC_EXPECTED_FILE // JAVAC_EXPECTED_FILE
// FILE: A.java // FILE: A.java
abstract public class A extends B { abstract public class A extends B {
@@ -1,24 +0,0 @@
// KT-1730 Method which has been implemented by Java is recognized to be abstract.
// FILE: C.java
public class C implements java.lang.CharSequence {
@Override
public int length() {
return 3;
}
@Override
public char charAt(int index) {
return 48;
}
@Override
public CharSequence subSequence(int start, int end) {
return "ab";
}
@Override
public String toString() {
return "abc";
}
}
// FILE: T.kt
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class T<!> : C()
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// KT-1730 Method which has been implemented by Java is recognized to be abstract. // KT-1730 Method which has been implemented by Java is recognized to be abstract.
// FILE: C.java // FILE: C.java
@@ -7501,6 +7501,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.kt"); runTest("compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.kt");
} }
@Test
@TestMetadata("mappedFunctionNotImplemented.kt")
public void testMappedFunctionNotImplemented() throws Exception {
runTest("compiler/testData/diagnostics/tests/declarationChecks/mappedFunctionNotImplemented.kt");
}
@Test @Test
@TestMetadata("mulitpleVarargParameters.kt") @TestMetadata("mulitpleVarargParameters.kt")
public void testMulitpleVarargParameters() throws Exception { public void testMulitpleVarargParameters() throws Exception {
@@ -7495,6 +7495,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.kt"); runTest("compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.kt");
} }
@Test
@TestMetadata("mappedFunctionNotImplemented.kt")
public void testMappedFunctionNotImplemented() throws Exception {
runTest("compiler/testData/diagnostics/tests/declarationChecks/mappedFunctionNotImplemented.kt");
}
@Test @Test
@TestMetadata("mulitpleVarargParameters.kt") @TestMetadata("mulitpleVarargParameters.kt")
public void testMulitpleVarargParameters() throws Exception { public void testMulitpleVarargParameters() throws Exception {
@@ -110,32 +110,6 @@ KtFirFunctionSymbol:
valueParameters: [] valueParameters: []
visibility: Public visibility: Public
KtFirFunctionSymbol:
annotatedType: [] kotlin/Char
annotationClassIds: []
annotations: []
callableIdIfNonLocal: java/lang/String.charAt
dispatchType: java/lang/String
hasStableParameterNames: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: OPEN
name: charAt
origin: JAVA
receiverType: null
symbolKind: MEMBER
typeParameters: []
valueParameters: [
KtFirValueParameterSymbol(p0)
]
visibility: Public
KtFirFunctionSymbol: KtFirFunctionSymbol:
annotatedType: [] kotlin/Int annotatedType: [] kotlin/Int
annotationClassIds: [] annotationClassIds: []
@@ -1511,9 +1485,9 @@ KtFirFunctionSymbol:
annotatedType: [] kotlin/Char annotatedType: [] kotlin/Char
annotationClassIds: [] annotationClassIds: []
annotations: [] annotations: []
callableIdIfNonLocal: kotlin/CharSequence.get callableIdIfNonLocal: java/lang/String.get
dispatchType: @EnhancedNullability kotlin/CharSequence dispatchType: java/lang/String
hasStableParameterNames: true hasStableParameterNames: false
isExtension: false isExtension: false
isExternal: false isExternal: false
isInfix: false isInfix: false
@@ -1522,14 +1496,14 @@ KtFirFunctionSymbol:
isOverride: false isOverride: false
isStatic: false isStatic: false
isSuspend: false isSuspend: false
modality: ABSTRACT modality: OPEN
name: get name: get
origin: LIBRARY origin: JAVA
receiverType: null receiverType: null
symbolKind: MEMBER symbolKind: MEMBER
typeParameters: [] typeParameters: []
valueParameters: [ valueParameters: [
KtFirValueParameterSymbol(index) KtFirValueParameterSymbol(p0)
] ]
visibility: Public visibility: Public