diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 0d5ca0223d5..7c944f26b04 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -17215,6 +17215,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/j+k/protectedStaticSamePackage.kt"); } + @Test + @TestMetadata("rawOverride.kt") + public void testRawOverride() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/rawOverride.kt"); + } + @Test @TestMetadata("recursionWithJavaSyntheticProperty.kt") public void testRecursionWithJavaSyntheticProperty() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index f5cc8a5fdc3..3bae45c59f7 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -17215,6 +17215,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/j+k/protectedStaticSamePackage.kt"); } + @Test + @TestMetadata("rawOverride.kt") + public void testRawOverride() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/rawOverride.kt"); + } + @Test @TestMetadata("recursionWithJavaSyntheticProperty.kt") public void testRecursionWithJavaSyntheticProperty() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index c4c0fa00762..5cbbb2e1b57 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -17215,6 +17215,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/j+k/protectedStaticSamePackage.kt"); } + @Test + @TestMetadata("rawOverride.kt") + public void testRawOverride() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/rawOverride.kt"); + } + @Test @TestMetadata("recursionWithJavaSyntheticProperty.kt") public void testRecursionWithJavaSyntheticProperty() throws Exception { diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaOverrideChecker.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaOverrideChecker.kt index d738318b9c3..2fe6120f2a4 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaOverrideChecker.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaOverrideChecker.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractOverrideChecker +import org.jetbrains.kotlin.fir.scopes.jvm.computeJvmDescriptorRepresentation import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.StandardClassIds @@ -32,6 +33,10 @@ class JavaOverrideChecker internal constructor( baseType: ConeKotlinType, substitutor: ConeSubstitutor ): Boolean { + if (candidateType is ConeRawType) { + return candidateType.computeJvmDescriptorRepresentation() == baseType.computeJvmDescriptorRepresentation() + } + if (candidateType is ConeFlexibleType) return isEqualTypes(candidateType.lowerBound, baseType, substitutor) if (baseType is ConeFlexibleType) return isEqualTypes(candidateType, baseType.lowerBound, substitutor) if (candidateType is ConeClassLikeType && baseType is ConeClassLikeType) { diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/SignatureUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/SignatureUtils.kt index b7968d0eef2..56d0a983264 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/SignatureUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/scopes/jvm/SignatureUtils.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.fir.containingClass import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.FirImplicitAnyTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitNullableAnyTypeRef @@ -44,7 +45,7 @@ fun FirFunction.computeJvmDescriptor( append("(") for (parameter in valueParameters) { - typeConversion(parameter.returnTypeRef)?.let { appendConeType(it, typeConversion) } + typeConversion(parameter.returnTypeRef)?.let { appendConeType(it, typeConversion, mutableSetOf()) } } append(")") @@ -52,7 +53,7 @@ fun FirFunction.computeJvmDescriptor( if (this@computeJvmDescriptor !is FirSimpleFunction || returnTypeRef.isVoid()) { append("V") } else { - typeConversion(returnTypeRef)?.let { appendConeType(it, typeConversion) } + typeConversion(returnTypeRef)?.let { appendConeType(it, typeConversion, mutableSetOf()) } } } } @@ -68,7 +69,16 @@ private val PRIMITIVE_TYPE_SIGNATURE: Map = mapOf( "Double" to "D", ) -private fun StringBuilder.appendConeType(coneType: ConeKotlinType, typeConversion: (FirTypeRef) -> ConeKotlinType?) { +fun ConeKotlinType.computeJvmDescriptorRepresentation( + typeConversion: (FirTypeRef) -> ConeKotlinType? = FirTypeRef::coneTypeSafe +): String = buildString { + appendConeType(this@computeJvmDescriptorRepresentation, typeConversion, mutableSetOf()) +} + +private fun StringBuilder.appendConeType( + coneType: ConeKotlinType, typeConversion: (FirTypeRef) -> ConeKotlinType?, + visitedTypeParameters: MutableSet, +) { (coneType as? ConeClassLikeType)?.let { val classId = it.lookupTag.classId if (classId.packageFqName.toString() == "kotlin") { @@ -88,7 +98,7 @@ private fun StringBuilder.appendConeType(coneType: ConeKotlinType, typeConversio type.typeArguments.forEach { typeArg -> when (typeArg) { ConeStarProjection -> append("*") - is ConeKotlinTypeProjection -> appendConeType(typeArg.type, typeConversion) + is ConeKotlinTypeProjection -> appendConeType(typeArg.type, typeConversion, visitedTypeParameters) } } } else { @@ -108,20 +118,23 @@ private fun StringBuilder.appendConeType(coneType: ConeKotlinType, typeConversio is ConeTypeParameterType -> { // TODO: 1. unannotated bounds are probably flexible, so this isn't right; // 2. shouldn't this always take the first bound and recurse if it's also a type parameter? - coneType.lookupTag.typeParameterSymbol.fir.bounds.firstNotNullOfOrNull { - val converted = typeConversion(it) - if (converted is ConeClassLikeType) it to converted else null - }?.let { (firBound, coneBound) -> - // TODO: pretty sure Java type conversion does not produce either of these - if (firBound !is FirImplicitNullableAnyTypeRef && firBound !is FirImplicitAnyTypeRef) { - appendClassLikeType(coneBound) - return + + if (visitedTypeParameters.add(coneType.lookupTag.typeParameterSymbol)) { + coneType.lookupTag.typeParameterSymbol.fir.bounds.firstNotNullOfOrNull { + val converted = typeConversion(it) + if (converted != null) it to converted else null + }?.let { (firBound, coneBound) -> + // TODO: pretty sure Java type conversion does not produce either of these + if (firBound !is FirImplicitNullableAnyTypeRef && firBound !is FirImplicitAnyTypeRef) { + appendConeType(coneBound, typeConversion, visitedTypeParameters) + return + } } } append("Ljava/lang/Object;") } - is ConeDefinitelyNotNullType -> appendConeType(coneType.original, typeConversion) - is ConeFlexibleType -> appendConeType(coneType.lowerBound, typeConversion) + is ConeDefinitelyNotNullType -> appendConeType(coneType.original, typeConversion, visitedTypeParameters) + is ConeFlexibleType -> appendConeType(coneType.lowerBound, typeConversion, visitedTypeParameters) else -> Unit // TODO: throw an error? should check that Java type conversion/enhancement can only produce these cone types } } diff --git a/compiler/testData/diagnostics/tests/j+k/rawOverride.kt b/compiler/testData/diagnostics/tests/j+k/rawOverride.kt new file mode 100644 index 00000000000..1dd5744c95f --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/rawOverride.kt @@ -0,0 +1,25 @@ +// SKIP_TXT +// FIR_IDENTICAL + +// FILE: ObjectStubSerializer.java +import org.jetbrains.annotations.*; + +public interface ObjectStubSerializer { + void indexStub(@NotNull Y stub); +} +// FILE: StubElement.java +public interface StubElement {} +// FILE: IStubFileElementType.java +import org.jetbrains.annotations.*; + +public class IStubFileElementType extends ObjectStubSerializer { + @Override + // IMO value parameter type should be T (may be I'm wrong) + public void indexStub(@NotNull final StubElement stub) {} +} + +// FILE: main.kt +class MakefileStubFileElementType : IStubFileElementType>() { + // FIR: ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED: indexStub, should be ok + // FE 1.0: Ok +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index f1a052d046a..ddffee95faa 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -17221,6 +17221,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/j+k/protectedStaticSamePackage.kt"); } + @Test + @TestMetadata("rawOverride.kt") + public void testRawOverride() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/rawOverride.kt"); + } + @Test @TestMetadata("recursionWithJavaSyntheticProperty.kt") public void testRecursionWithJavaSyntheticProperty() throws Exception {