From 09a1d54865bd7113ddea5520ad2bbd53bd09d574 Mon Sep 17 00:00:00 2001 From: Andrey Zinovyev Date: Thu, 19 Aug 2021 16:30:58 +0300 Subject: [PATCH] [FIR] Add JVM_RECORD_EXTENDS_CLASS diagnostic --- .../generator/diagnostics/FirJvmDiagnosticsList.kt | 3 +++ .../fir/analysis/diagnostics/jvm/FirJvmErrors.kt | 1 + .../jvm/checkers/declaration/FirJvmRecordChecker.kt | 11 +++++++++++ .../testsWithJava15/jvmRecord/supertypesCheck.fir.kt | 8 ++++---- .../api/fir/diagnostics/KtFirDataClassConverters.kt | 7 +++++++ .../frontend/api/fir/diagnostics/KtFirDiagnostics.kt | 5 +++++ .../api/fir/diagnostics/KtFirDiagnosticsImpl.kt | 8 ++++++++ 7 files changed, 39 insertions(+), 4 deletions(-) diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt index bc4ac129a8e..c9e07f3533d 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt @@ -72,6 +72,9 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") { val INNER_JVM_RECORD by error(PositioningStrategy.INNER_MODIFIER) val FIELD_IN_JVM_RECORD by error() val DELEGATION_BY_IN_JVM_RECORD by error() + val JVM_RECORD_EXTENDS_CLASS by error(PositioningStrategy.ACTUAL_DECLARATION_NAME) { + parameter("superType") + } } } diff --git a/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt b/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt index e4cb0c2259c..5120289d9ff 100644 --- a/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt +++ b/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt @@ -61,5 +61,6 @@ object FirJvmErrors { val INNER_JVM_RECORD by error0(SourceElementPositioningStrategies.INNER_MODIFIER) val FIELD_IN_JVM_RECORD by error0() val DELEGATION_BY_IN_JVM_RECORD by error0() + val JVM_RECORD_EXTENDS_CLASS by error1(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME) } diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRecordChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRecordChecker.kt index f0f80951af0..ddd200cec9d 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRecordChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/declaration/FirJvmRecordChecker.kt @@ -6,9 +6,12 @@ package org.jetbrains.kotlin.fir.analysis.jvm.checkers.declaration import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.FirFakeSourceElementKind +import org.jetbrains.kotlin.fir.FirRealSourceElementKind import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirRegularClassChecker +import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors @@ -19,6 +22,7 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.getAnnotationByFqName import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.languageVersionSettings +import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.name.FqName object FirJvmRecordChecker : FirRegularClassChecker() { @@ -88,5 +92,12 @@ object FirJvmRecordChecker : FirRegularClassChecker() { reporter.reportOn(decl.source, FirJvmErrors.DELEGATION_BY_IN_JVM_RECORD, context) } } + + declaration.superTypeRefs.firstOrNull()?.let { typeRef -> + if (typeRef.source?.kind != FirRealSourceElementKind) return@let + if (typeRef.toRegularClassSymbol(context.session)?.classKind == ClassKind.CLASS) { + reporter.reportOn(declaration.source, FirJvmErrors.JVM_RECORD_EXTENDS_CLASS, typeRef.coneType, context) + } + } } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/testsWithJava15/jvmRecord/supertypesCheck.fir.kt b/compiler/testData/diagnostics/tests/testsWithJava15/jvmRecord/supertypesCheck.fir.kt index 6624134fec9..62a0ab9f07a 100644 --- a/compiler/testData/diagnostics/tests/testsWithJava15/jvmRecord/supertypesCheck.fir.kt +++ b/compiler/testData/diagnostics/tests/testsWithJava15/jvmRecord/supertypesCheck.fir.kt @@ -7,16 +7,16 @@ abstract class Abstract interface I @JvmRecord -data class A1(val x: String) : Abstract(), I +data class A1(val x: String) : Abstract(), I @JvmRecord -data class A2(val x: String) : Any(), I +data class A2(val x: String) : Any(), I @JvmRecord -data class A3(val x: String) : Record(), I +data class A3(val x: String) : Record(), I @JvmRecord -data class A4(val x: String) : java.lang.Record(), I +data class A4(val x: String) : java.lang.Record(), I @JvmRecord data class A5(val x: String) : I diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index 4e6342b0f44..d5d6891cb4e 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -3598,4 +3598,11 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirJvmErrors.JVM_RECORD_EXTENDS_CLASS) { firDiagnostic -> + JvmRecordExtendsClassImpl( + firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a), + firDiagnostic as FirPsiDiagnostic, + token, + ) + } } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index 99ec28f7045..c3a1d8a8028 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -2505,4 +2505,9 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = DelegationByInJvmRecord::class } + abstract class JvmRecordExtendsClass : KtFirDiagnostic() { + override val diagnosticClass get() = JvmRecordExtendsClass::class + abstract val superType: KtType + } + } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 694e42087b6..58cf6c4e177 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -4063,3 +4063,11 @@ internal class DelegationByInJvmRecordImpl( override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) } +internal class JvmRecordExtendsClassImpl( + override val superType: KtType, + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.JvmRecordExtendsClass(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} +