From c3a6ba52f6e22bffd47dba48c2c2b9c7c8137b51 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Tue, 22 Jun 2021 14:31:37 +0300 Subject: [PATCH] [FIR] Implement CLASS_CANNOT_BE_EXTENDED_DIRECTLY --- .../checkers/generator/diagnostics/FirDiagnosticsList.kt | 3 +++ .../kotlin/fir/analysis/diagnostics/FirErrors.kt | 1 + .../checkers/declaration/FirSupertypesChecker.kt | 5 +++++ .../fir/analysis/diagnostics/FirDefaultErrorMessages.kt | 2 ++ .../diagnostics/tests/enum/extendingEnumDirectly.fir.kt | 9 --------- .../diagnostics/tests/enum/extendingEnumDirectly.kt | 1 + .../api/fir/diagnostics/KtFirDataClassConverters.kt | 7 +++++++ .../frontend/api/fir/diagnostics/KtFirDiagnostics.kt | 5 +++++ .../frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt | 8 ++++++++ 9 files changed, 32 insertions(+), 9 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/enum/extendingEnumDirectly.fir.kt diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 444740ffba4..763c7c86fe5 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -124,6 +124,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val SUPERTYPE_INITIALIZED_IN_INTERFACE by error() val INTERFACE_WITH_SUPERCLASS by error() val FINAL_SUPERTYPE by error() + val CLASS_CANNOT_BE_EXTENDED_DIRECTLY by error { + parameter("classSymbol") + } val SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE by error() val SINGLETON_IN_SUPERTYPE by error() val NULLABLE_SUPERTYPE by error(PositioningStrategy.QUESTION_MARK_BY_TYPE) diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 86b1996e475..4c733d81bfb 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -134,6 +134,7 @@ object FirErrors { val SUPERTYPE_INITIALIZED_IN_INTERFACE by error0() val INTERFACE_WITH_SUPERCLASS by error0() val FINAL_SUPERTYPE by error0() + val CLASS_CANNOT_BE_EXTENDED_DIRECTLY by error1() val SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE by error0() val SINGLETON_IN_SUPERTYPE by error0() val NULLABLE_SUPERTYPE by error0(SourceElementPositioningStrategies.QUESTION_MARK_BY_TYPE) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSupertypesChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSupertypesChecker.kt index dab2b850731..8a22186be96 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSupertypesChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSupertypesChecker.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.utils.addToStdlib.safeAs object FirSupertypesChecker : FirClassChecker() { @@ -106,6 +107,10 @@ object FirSupertypesChecker : FirClassChecker() { } } } + + if (symbol is FirRegularClassSymbol && symbol.classId == StandardClassIds.Enum) { + reporter.reportOn(superTypeRef.source, FirErrors.CLASS_CANNOT_BE_EXTENDED_DIRECTLY, symbol, context) + } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index 21f2de51d0f..838d0ed97bb 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -65,6 +65,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAN_BE_VAL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAPTURED_MEMBER_VAL_INITIALIZATION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAPTURED_VAL_INITIALIZATION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CATCH_PARAMETER_WITH_DEFAULT_VALUE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CLASS_CANNOT_BE_EXTENDED_DIRECTLY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CLASS_IN_SUPERTYPE_FOR_ENUM import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CLASS_LITERAL_LHS_NOT_A_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPONENT_FUNCTION_AMBIGUITY @@ -453,6 +454,7 @@ class FirDefaultErrorMessages { map.put(SUPERTYPE_INITIALIZED_IN_INTERFACE, "Interfaces cannot initialize supertypes") map.put(INTERFACE_WITH_SUPERCLASS, "An interface cannot inherit from a class") map.put(FINAL_SUPERTYPE, "This type is final, so it cannot be inherited from") + map.put(CLASS_CANNOT_BE_EXTENDED_DIRECTLY, "Class {0} cannot be extended directly", SYMBOL) map.put(SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE, "Extension function type is not allowed as supertypes") map.put(SINGLETON_IN_SUPERTYPE, "Cannot inherit from a singleton") map.put(NULLABLE_SUPERTYPE, "A supertype cannot be nullable") diff --git a/compiler/testData/diagnostics/tests/enum/extendingEnumDirectly.fir.kt b/compiler/testData/diagnostics/tests/enum/extendingEnumDirectly.fir.kt deleted file mode 100644 index be44ac109a9..00000000000 --- a/compiler/testData/diagnostics/tests/enum/extendingEnumDirectly.fir.kt +++ /dev/null @@ -1,9 +0,0 @@ -class Test1 : Enum("", 0) - -class Outer { - class Test2 : Enum("", 0) -} - -fun outer() { - class Test3 : Enum("", 0) -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/enum/extendingEnumDirectly.kt b/compiler/testData/diagnostics/tests/enum/extendingEnumDirectly.kt index 3f71edb0bd8..8bab38d163e 100644 --- a/compiler/testData/diagnostics/tests/enum/extendingEnumDirectly.kt +++ b/compiler/testData/diagnostics/tests/enum/extendingEnumDirectly.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL class Test1 : Enum("", 0) class Outer { 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 a750799be59..6901919797e 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 @@ -351,6 +351,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.CLASS_CANNOT_BE_EXTENDED_DIRECTLY) { firDiagnostic -> + ClassCannotBeExtendedDirectlyImpl( + firSymbolBuilder.classifierBuilder.buildClassLikeSymbol(firDiagnostic.a.fir), + firDiagnostic as FirPsiDiagnostic, + token, + ) + } add(FirErrors.SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE) { firDiagnostic -> SupertypeIsExtensionFunctionTypeImpl( firDiagnostic as FirPsiDiagnostic, 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 2490e85ef8b..049c4e0ca8d 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 @@ -266,6 +266,11 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = FinalSupertype::class } + abstract class ClassCannotBeExtendedDirectly : KtFirDiagnostic() { + override val diagnosticClass get() = ClassCannotBeExtendedDirectly::class + abstract val classSymbol: KtClassLikeSymbol + } + abstract class SupertypeIsExtensionFunctionType : KtFirDiagnostic() { override val diagnosticClass get() = SupertypeIsExtensionFunctionType::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 4413bf62ab9..eb62f8cfd18 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 @@ -408,6 +408,14 @@ internal class FinalSupertypeImpl( override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) } +internal class ClassCannotBeExtendedDirectlyImpl( + override val classSymbol: KtClassLikeSymbol, + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.ClassCannotBeExtendedDirectly(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + internal class SupertypeIsExtensionFunctionTypeImpl( firDiagnostic: FirPsiDiagnostic, override val token: ValidityToken,