[FIR] FirJavaFacade: do not duplicate record constructor

The fresh version of intellij has all record-related declarations,
so an additional fake constructor leads to errors like
KTIJ-25364 (OVERLOAD_RESOLUTION_AMBIGUITY)

^KTIJ-25366 Fixed
^KTIJ-25364 Fixed
^KTIJ-25368 Fixed
^KTIJ-25370 Fixed
This commit is contained in:
Dmitrii Gridin
2023-07-11 17:52:56 +02:00
committed by Space Team
parent 97a12af03e
commit b67b37cdb3
8 changed files with 127 additions and 30 deletions
@@ -33559,6 +33559,18 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecords.kt"); runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecords.kt");
} }
@Test
@TestMetadata("simpleRecordsDefaultConstructor.kt")
public void testSimpleRecordsDefaultConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecordsDefaultConstructor.kt");
}
@Test
@TestMetadata("simpleRecordsWithSecondaryConstructor.kt")
public void testSimpleRecordsWithSecondaryConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecordsWithSecondaryConstructor.kt");
}
@Test @Test
@TestMetadata("supertypesCheck.kt") @TestMetadata("supertypesCheck.kt")
public void testSupertypesCheck() throws Exception { public void testSupertypesCheck() throws Exception {
@@ -33559,6 +33559,18 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecords.kt"); runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecords.kt");
} }
@Test
@TestMetadata("simpleRecordsDefaultConstructor.kt")
public void testSimpleRecordsDefaultConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecordsDefaultConstructor.kt");
}
@Test
@TestMetadata("simpleRecordsWithSecondaryConstructor.kt")
public void testSimpleRecordsWithSecondaryConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecordsWithSecondaryConstructor.kt");
}
@Test @Test
@TestMetadata("supertypesCheck.kt") @TestMetadata("supertypesCheck.kt")
public void testSupertypesCheck() throws Exception { public void testSupertypesCheck() throws Exception {
@@ -33559,6 +33559,18 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecords.kt"); runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecords.kt");
} }
@Test
@TestMetadata("simpleRecordsDefaultConstructor.kt")
public void testSimpleRecordsDefaultConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecordsDefaultConstructor.kt");
}
@Test
@TestMetadata("simpleRecordsWithSecondaryConstructor.kt")
public void testSimpleRecordsWithSecondaryConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecordsWithSecondaryConstructor.kt");
}
@Test @Test
@TestMetadata("supertypesCheck.kt") @TestMetadata("supertypesCheck.kt")
public void testSupertypesCheck() throws Exception { public void testSupertypesCheck() throws Exception {
@@ -33673,6 +33673,18 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecords.kt"); runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecords.kt");
} }
@Test
@TestMetadata("simpleRecordsDefaultConstructor.kt")
public void testSimpleRecordsDefaultConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecordsDefaultConstructor.kt");
}
@Test
@TestMetadata("simpleRecordsWithSecondaryConstructor.kt")
public void testSimpleRecordsWithSecondaryConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecordsWithSecondaryConstructor.kt");
}
@Test @Test
@TestMetadata("supertypesCheck.kt") @TestMetadata("supertypesCheck.kt")
public void testSupertypesCheck() throws Exception { public void testSupertypesCheck() throws Exception {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.java package org.jetbrains.kotlin.fir.java
import com.intellij.psi.impl.light.LightRecordCanonicalConstructor
import org.jetbrains.kotlin.* import org.jetbrains.kotlin.*
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
@@ -320,6 +321,7 @@ abstract class FirJavaFacade(
if (javaClassDeclaredConstructors.isEmpty() if (javaClassDeclaredConstructors.isEmpty()
&& javaClass.classKind == ClassKind.CLASS && javaClass.classKind == ClassKind.CLASS
&& !javaClass.isRecord
&& javaClass.hasDefaultConstructor() && javaClass.hasDefaultConstructor()
) { ) {
declarations += convertJavaConstructorToFir( declarations += convertJavaConstructorToFir(
@@ -441,39 +443,46 @@ abstract class FirJavaFacade(
} }
} }
destination += buildJavaConstructor { /**
source = javaClass.toSourceElement(KtFakeSourceElementKind.ImplicitJavaRecordConstructor) * It is possible that JavaClass already has a synthetic primary constructor ([LightRecordCanonicalConstructor])
this.moduleData = moduleData * Such behavior depends on a platform version and psi providers
isFromSource = javaClass.isFromSource * (e.g., in IntelliJ plugin Java class can have additional declarations)
*/
if (destination.none { it is FirJavaConstructor && it.isPrimary }) {
destination += buildJavaConstructor {
source = javaClass.toSourceElement(KtFakeSourceElementKind.ImplicitJavaRecordConstructor)
this.moduleData = moduleData
isFromSource = javaClass.isFromSource
val constructorId = CallableId(classId, classId.shortClassName) val constructorId = CallableId(classId, classId.shortClassName)
symbol = FirConstructorSymbol(constructorId) symbol = FirConstructorSymbol(constructorId)
status = FirResolvedDeclarationStatusImpl( status = FirResolvedDeclarationStatusImpl(
Visibilities.Public, Visibilities.Public,
Modality.FINAL, Modality.FINAL,
EffectiveVisibility.Public EffectiveVisibility.Public
) )
visibility = Visibilities.Public visibility = Visibilities.Public
isPrimary = true isPrimary = true
returnTypeRef = classType.toFirResolvedTypeRef() returnTypeRef = classType.toFirResolvedTypeRef()
dispatchReceiverType = null dispatchReceiverType = null
typeParameters += classTypeParameters.toRefs() typeParameters += classTypeParameters.toRefs()
annotationBuilder = { emptyList() } annotationBuilder = { emptyList() }
javaClass.recordComponents.mapTo(valueParameters) { component -> javaClass.recordComponents.mapTo(valueParameters) { component ->
buildJavaValueParameter { buildJavaValueParameter {
containingFunctionSymbol = this@buildJavaConstructor.symbol containingFunctionSymbol = this@buildJavaConstructor.symbol
source = component.toSourceElement(KtFakeSourceElementKind.ImplicitRecordConstructorParameter) source = component.toSourceElement(KtFakeSourceElementKind.ImplicitRecordConstructorParameter)
this.moduleData = moduleData this.moduleData = moduleData
isFromSource = component.isFromSource isFromSource = component.isFromSource
returnTypeRef = component.type.toFirJavaTypeRef(session, javaTypeParameterStack) returnTypeRef = component.type.toFirJavaTypeRef(session, javaTypeParameterStack)
name = component.name name = component.name
isVararg = component.isVararg isVararg = component.isVararg
annotationBuilder = { emptyList() } annotationBuilder = { emptyList() }
}
} }
}.apply {
containingClassForStaticMemberAttr = classType.lookupTag
} }
}.apply {
containingClassForStaticMemberAttr = classType.lookupTag
} }
} }
@@ -636,7 +645,7 @@ abstract class FirJavaFacade(
hasStableParameterNames = false hasStableParameterNames = false
} }
this.visibility = visibility this.visibility = visibility
isPrimary = javaConstructor == null isPrimary = javaConstructor == null || source?.psi is LightRecordCanonicalConstructor
returnTypeRef = buildResolvedTypeRef { returnTypeRef = buildResolvedTypeRef {
type = ownerClassBuilder.buildSelfTypeRef() type = ownerClassBuilder.buildSelfTypeRef()
} }
@@ -0,0 +1,12 @@
// FIR_IDENTICAL
// LANGUAGE: +JvmRecordSupport
// FILE: MyRecord.java
public record MyRecord(String str) {}
// FILE: main.kt
fun foo() {
MyRecord("") // OK
MyRecord<!NO_VALUE_FOR_PARAMETER!>()<!> // error
}
@@ -0,0 +1,16 @@
// FIR_IDENTICAL
// LANGUAGE: +JvmRecordSupport
// FILE: MyRecord.java
public record MyRecord(String string, int number) {
public MyRecord(Long number, String string) {
this(string, 4)
}
}
// FILE: main.kt
fun foo(mr: MyRecord) {
MyRecord("", 1)
MyRecord(4L, "")
}
@@ -34517,6 +34517,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecords.kt"); runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecords.kt");
} }
@Test
@TestMetadata("simpleRecordsDefaultConstructor.kt")
public void testSimpleRecordsDefaultConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecordsDefaultConstructor.kt");
}
@Test
@TestMetadata("simpleRecordsWithSecondaryConstructor.kt")
public void testSimpleRecordsWithSecondaryConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava17/jvmRecord/simpleRecordsWithSecondaryConstructor.kt");
}
@Test @Test
@TestMetadata("supertypesCheck.kt") @TestMetadata("supertypesCheck.kt")
public void testSupertypesCheck() throws Exception { public void testSupertypesCheck() throws Exception {