From a18daa5d62c73afe60a8042dd45d5a36f177d67a Mon Sep 17 00:00:00 2001 From: Tianyu Geng Date: Thu, 22 Jul 2021 16:54:25 -0700 Subject: [PATCH] FIR checker: report type parameters on anonymous objects --- .../diagnostics/FirDiagnosticsList.kt | 1 + .../fir/analysis/diagnostics/FirErrors.kt | 1 + .../checkers/CommonDeclarationCheckers.kt | 2 +- .../FirTypeParametersInObjectChecker.kt | 25 ++++++++++++++++--- .../diagnostics/FirDefaultErrorMessages.kt | 3 +++ .../typeParametersInAnnonymousObject.fir.kt | 14 +++++------ ...eParametersInAnnonymousObject_after.fir.kt | 14 +++++------ .../diagnostics/KtFirDataClassConverters.kt | 6 +++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 4 +++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 7 ++++++ 10 files changed, 58 insertions(+), 19 deletions(-) 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 c9337b67a94..93dd3ddddc1 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 @@ -500,6 +500,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { parameter("outer") } val TYPE_PARAMETERS_IN_OBJECT by error(PositioningStrategy.TYPE_PARAMETERS_LIST) + val TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT by error(PositioningStrategy.TYPE_PARAMETERS_LIST) val ILLEGAL_PROJECTION_USAGE by error() val TYPE_PARAMETERS_IN_ENUM by error() val CONFLICTING_PROJECTION by error(PositioningStrategy.VARIANCE_MODIFIER) { 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 95d7aaa518b..222ad75cd7a 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 @@ -333,6 +333,7 @@ object FirErrors { val NO_TYPE_ARGUMENTS_ON_RHS by error2>() val OUTER_CLASS_ARGUMENTS_REQUIRED by error1() val TYPE_PARAMETERS_IN_OBJECT by error0(SourceElementPositioningStrategies.TYPE_PARAMETERS_LIST) + val TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT by error0(SourceElementPositioningStrategies.TYPE_PARAMETERS_LIST) val ILLEGAL_PROJECTION_USAGE by error0() val TYPE_PARAMETERS_IN_ENUM by error0() val CONFLICTING_PROJECTION by error1(SourceElementPositioningStrategies.VARIANCE_MODIFIER) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index 7dc3cbcc99c..81f3febe7cb 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -72,6 +72,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirMemberFunctionsChecker, FirMemberPropertiesChecker, FirImplementationMismatchChecker, + FirTypeParametersInObjectChecker, ) override val regularClassCheckers: Set @@ -89,7 +90,6 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirMethodOfAnyImplementedInInterfaceChecker, FirDataClassPrimaryConstructorChecker, FirPrimaryConstructorSuperTypeChecker, - FirTypeParametersInObjectChecker, FirFunInterfaceDeclarationChecker, FirNestedClassChecker, FirInlineClassDeclarationChecker, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTypeParametersInObjectChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTypeParametersInObjectChecker.kt index a0fa3fe7bb4..afeb2a0f0dc 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTypeParametersInObjectChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTypeParametersInObjectChecker.kt @@ -5,21 +5,38 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration +import org.jetbrains.kotlin.KtNodeTypes +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn +import org.jetbrains.kotlin.fir.analysis.getChild +import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject +import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.languageVersionSettings -object FirTypeParametersInObjectChecker : FirRegularClassChecker() { - override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) { +object FirTypeParametersInObjectChecker : FirClassChecker() { + override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) { if (declaration.classKind != ClassKind.OBJECT) { return } - if (declaration.typeParameters.isNotEmpty()) { - reporter.reportOn(declaration.source, FirErrors.TYPE_PARAMETERS_IN_OBJECT, context) + when (declaration) { + is FirRegularClass -> if (declaration.typeParameters.isNotEmpty()) { + reporter.reportOn(declaration.source, FirErrors.TYPE_PARAMETERS_IN_OBJECT, context) + } + is FirAnonymousObject -> if (declaration.source?.getChild(KtNodeTypes.TYPE_PARAMETER_LIST, depth = 1) != null) { + val diagnosticFactory = + if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitTypeParametersInAnonymousObjects)) { + FirErrors.TYPE_PARAMETERS_IN_OBJECT + } else { + FirErrors.TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT + } + reporter.reportOn(declaration.source, diagnosticFactory, 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 8e1e85018c9..9b466efbee0 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 @@ -406,6 +406,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_ARGUMENTS_NO import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_CANT_BE_USED_FOR_CONST_VAL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_MISMATCH +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_IN_ENUM import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_IN_OBJECT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_NOT_ALLOWED @@ -825,6 +826,8 @@ class FirDefaultErrorMessages { RENDER_CLASS_OR_OBJECT_NAME ) map.put(TYPE_PARAMETERS_IN_OBJECT, "Type parameters are not allowed for objects") + map.put(TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT, "Type parameters for anonymous objects are deprecated") + // map.put(ILLEGAL_PROJECTION_USAGE, ...) // & map.put(TYPE_PARAMETERS_IN_ENUM, "Enum class cannot have type parameters") map.put( diff --git a/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject.fir.kt b/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject.fir.kt index c12c992f922..2c8f0fa106a 100644 --- a/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject.fir.kt +++ b/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject.fir.kt @@ -3,23 +3,23 @@ // ISSUE: KT-28999 fun case_1() { - val x = object { } // type of x is + val x = object { } // type of x is } fun case_2() { - val x = object> { } + val x = object> { } } fun case_3() { - val x = object where T : Comparable { } // ERROR: Where clause is not allowed for objects + val x = object where T : Comparable { } // ERROR: Where clause is not allowed for objects } -val x = object> { +val x = object> { fun test() = 10 as T // OK } fun case_4() { - val x = object { + val x = object { fun test() = 10 as T } @@ -27,7 +27,7 @@ fun case_4() { } inline fun case_5() { - val x = object { + val x = object { fun test() = 10 as T } @@ -38,7 +38,7 @@ inline fun case_5() { println(z) } - val a = object { + val a = object { fun test() = 42 as A } diff --git a/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject_after.fir.kt b/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject_after.fir.kt index c9f10467812..35905f5cdc0 100644 --- a/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject_after.fir.kt +++ b/compiler/testData/diagnostics/tests/classObjects/typeParametersInAnnonymousObject_after.fir.kt @@ -3,23 +3,23 @@ // ISSUE: KT-28999 fun case_1() { - val x = object { } // type of x is + val x = object { } // type of x is } fun case_2() { - val x = object> { } + val x = object> { } } fun case_3() { - val x = object where T : Comparable { } // ERROR: Where clause is not allowed for objects + val x = object where T : Comparable { } // ERROR: Where clause is not allowed for objects } -val x = object> { +val x = object> { fun test() = 10 as T // OK } fun case_4() { - val x = object { + val x = object { fun test() = 10 as T } @@ -27,7 +27,7 @@ fun case_4() { } inline fun case_5() { - val x = object { + val x = object { fun test() = 10 as T } @@ -38,7 +38,7 @@ inline fun case_5() { println(z) } - val a = object { + val a = object { fun test() = 42 as A } 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 590c8653f74..9bb1d781ce4 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 @@ -1486,6 +1486,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT) { firDiagnostic -> + TypeParametersInAnonymousObjectImpl( + firDiagnostic as FirPsiDiagnostic, + token, + ) + } add(FirErrors.ILLEGAL_PROJECTION_USAGE) { firDiagnostic -> IllegalProjectionUsageImpl( 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 693a0e3e444..fa5ef54b1e1 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 @@ -1057,6 +1057,10 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = TypeParametersInObject::class } + abstract class TypeParametersInAnonymousObject : KtFirDiagnostic() { + override val diagnosticClass get() = TypeParametersInAnonymousObject::class + } + abstract class IllegalProjectionUsage : KtFirDiagnostic() { override val diagnosticClass get() = IllegalProjectionUsage::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 da1abde2d15..2c4bf028d88 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 @@ -1691,6 +1691,13 @@ internal class TypeParametersInObjectImpl( override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) } +internal class TypeParametersInAnonymousObjectImpl( + firDiagnostic: FirPsiDiagnostic, + override val token: ValidityToken, +) : KtFirDiagnostic.TypeParametersInAnonymousObject(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic) +} + internal class IllegalProjectionUsageImpl( firDiagnostic: FirPsiDiagnostic, override val token: ValidityToken,