From c8381e9b0f64b8577987866c6f8aef8202647eea Mon Sep 17 00:00:00 2001 From: Andrey Zinovyev Date: Thu, 19 Aug 2021 12:03:11 +0300 Subject: [PATCH] [FIR] Add NON_FINAL_JVM_RECORD diagnostic --- .../generator/diagnostics/FirJvmDiagnosticsList.kt | 1 + .../generator/diagnostics/model/RegularDiagnosticData.kt | 1 + .../kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt | 2 ++ .../jvm/checkers/declaration/FirJvmRecordChecker.kt | 6 ++++++ .../diagnostics/LightTreePositioningStrategies.kt | 8 ++++++++ .../diagnostics/SourceElementPositioningStrategies.kt | 5 +++++ .../jetbrains/kotlin/diagnostics/PositioningStrategies.kt | 3 +++ .../tests/testsWithJava15/jvmRecord/diagnostics.fir.kt | 6 +++--- .../api/fir/diagnostics/KtFirDataClassConverters.kt | 6 ++++++ .../idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt | 4 ++++ .../frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt | 7 +++++++ 11 files changed, 46 insertions(+), 3 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 3e01e1fdfc1..dfebb25b2c5 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 @@ -63,6 +63,7 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") { val RECORDS by object : DiagnosticGroup("JVM Records") { val LOCAL_JVM_RECORD by error() + val NON_FINAL_JVM_RECORD by error(PositioningStrategy.NON_FINAL_MODIFIER_OR_NAME) } } diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/model/RegularDiagnosticData.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/model/RegularDiagnosticData.kt index 38c55759ecd..06d18b9c198 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/model/RegularDiagnosticData.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/model/RegularDiagnosticData.kt @@ -104,6 +104,7 @@ enum class PositioningStrategy(private val strategy: String? = null) { LABEL, COMMAS, OPERATOR_MODIFIER, + NON_FINAL_MODIFIER_OR_NAME, ; 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 43f8f1237f5..9fa28c299ed 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 @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics.jvm import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.LanguageFeature.ProhibitJvmOverloadsOnConstructorsOfAnnotationClasses import org.jetbrains.kotlin.fir.analysis.diagnostics.* +import org.jetbrains.kotlin.fir.analysis.diagnostics.SourceElementPositioningStrategies import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtAnnotationEntry @@ -51,5 +52,6 @@ object FirJvmErrors { // JVM Records val LOCAL_JVM_RECORD by error0() + val NON_FINAL_JVM_RECORD by error0(SourceElementPositioningStrategies.NON_FINAL_MODIFIER_OR_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 13bcca82a71..c6f7bc82594 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 @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.getAnnotationByFqName +import org.jetbrains.kotlin.fir.declarations.utils.isFinal import org.jetbrains.kotlin.fir.declarations.utils.isLocal import org.jetbrains.kotlin.name.FqName @@ -24,6 +25,11 @@ object FirJvmRecordChecker : FirRegularClassChecker() { if (declaration.isLocal) { reporter.reportOn(annotationSource, FirJvmErrors.LOCAL_JVM_RECORD, context) + return + } + + if (!declaration.isFinal) { + reporter.reportOn(declaration.source, FirJvmErrors.NON_FINAL_JVM_RECORD, context) } } } \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt index 40d9afd0ed7..14d0b89e378 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt @@ -933,6 +933,14 @@ object LightTreePositioningStrategies { } } } + + val NON_FINAL_MODIFIER_OR_NAME: LightTreePositioningStrategy = ModifierSetBasedLightTreePositioningStrategy( + TokenSet.create( + KtTokens.ABSTRACT_KEYWORD, + KtTokens.OPEN_KEYWORD, + KtTokens.SEALED_KEYWORD + ) + ) } fun FirSourceElement.hasValOrVar(): Boolean = diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt index 8dca98b8065..3c9597cc46a 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt @@ -309,4 +309,9 @@ object SourceElementPositioningStrategies { LightTreePositioningStrategies.OPERATOR_MODIFIER, PositioningStrategies.OPERATOR_MODIFIER ) + + val NON_FINAL_MODIFIER_OR_NAME = SourceElementPositioningStrategy( + LightTreePositioningStrategies.NON_FINAL_MODIFIER_OR_NAME, + PositioningStrategies.NON_FINAL_MODIFIER_OR_NAME + ) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt index 798f208ff35..7e206de7822 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt @@ -961,6 +961,9 @@ object PositioningStrategies { } } + val NON_FINAL_MODIFIER_OR_NAME: PositioningStrategy = + ModifierSetBasedPositioningStrategy(TokenSet.create(KtTokens.ABSTRACT_KEYWORD, KtTokens.OPEN_KEYWORD, KtTokens.SEALED_KEYWORD)) + /** * @param locateReferencedName whether to remove any nested parentheses while locating the reference element. This is useful for * diagnostics on super and unresolved references. For example, with the following, only the part inside the parentheses should be diff --git a/compiler/testData/diagnostics/tests/testsWithJava15/jvmRecord/diagnostics.fir.kt b/compiler/testData/diagnostics/tests/testsWithJava15/jvmRecord/diagnostics.fir.kt index 64a05295854..4b78c26430d 100644 --- a/compiler/testData/diagnostics/tests/testsWithJava15/jvmRecord/diagnostics.fir.kt +++ b/compiler/testData/diagnostics/tests/testsWithJava15/jvmRecord/diagnostics.fir.kt @@ -25,13 +25,13 @@ class A4(var name: String) class A5(vararg val name: String, y: Int) @JvmRecord -open class A6(val x: String) +open class A6(val x: String) @JvmRecord -abstract class A7(val x: String) +abstract class A7(val x: String) @JvmRecord -sealed class A8(val x: String) +sealed class A8(val x: String) @JvmRecord enum class A9(val x: String) { 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 08e74da7281..609fdfd67e3 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 @@ -3544,4 +3544,10 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirJvmErrors.NON_FINAL_JVM_RECORD) { firDiagnostic -> + NonFinalJvmRecordImpl( + 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 d64e3360296..ab2791f2613 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 @@ -2469,4 +2469,8 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = LocalJvmRecord::class } + abstract class NonFinalJvmRecord : KtFirDiagnostic() { + override val diagnosticClass get() = NonFinalJvmRecord::class + } + } 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 ca869c4c58c..5fde2322be4 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 @@ -4000,3 +4000,10 @@ internal class LocalJvmRecordImpl( override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) } +internal class NonFinalJvmRecordImpl( + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.NonFinalJvmRecord(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} +