From 6e8bad6ef632734e9d6814ec1e5b3c6f4f43486e Mon Sep 17 00:00:00 2001 From: Tianyu Geng Date: Tue, 23 Feb 2021 20:42:34 -0800 Subject: [PATCH] FIR: Implement data class constructor checker --- .../primaryConstructorRequiredForDataClass.kt | 2 +- .../testData/resolve/incorrectDataClass.kt | 2 +- .../smartcasts/lambdas/lambdaInWhenBranch.kt | 2 +- .../diagnostics/FirDiagnosticsList.kt | 11 ++++- .../fir/analysis/diagnostics/FirErrors.kt | 6 ++- .../fir/analysis/checkers/FirHelpers.kt | 21 ++++++--- .../FirDataClassPrimaryConstructorChecker.kt | 45 +++++++++++++++++++ ...yConstructorRequiredForDataClassChecker.kt | 29 ------------ .../diagnostics/FirDefaultErrorMessages.kt | 6 +++ .../fir/checkers/CommonDeclarationCheckers.kt | 2 +- .../tests/dataClasses/dataClassNoName.fir.kt | 6 +-- .../dataClasses/dataClassVarargParam.fir.kt | 4 +- .../tests/dataClasses/emptyConstructor.fir.kt | 6 --- .../tests/dataClasses/emptyConstructor.kt | 1 + .../tests/dataClasses/noConstructor.fir.kt | 2 +- .../secondaryConstructors/dataClasses.fir.kt | 2 +- .../p-5/neg/1.1.fir.kt | 8 ++-- .../p-5/neg/1.2.fir.kt | 20 ++++----- .../diagnostics/KtFirDataClassConverters.kt | 19 ++++++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 13 ++++++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 22 +++++++++ 21 files changed, 160 insertions(+), 69 deletions(-) create mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDataClassPrimaryConstructorChecker.kt delete mode 100644 compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorRequiredForDataClassChecker.kt delete mode 100644 compiler/testData/diagnostics/tests/dataClasses/emptyConstructor.fir.kt diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/primaryConstructorRequiredForDataClass.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/primaryConstructorRequiredForDataClass.kt index b2792655a77..948c6171ae5 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/primaryConstructorRequiredForDataClass.kt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/primaryConstructorRequiredForDataClass.kt @@ -1,4 +1,4 @@ -data class A {} +data class A {} data class B { constructor() diff --git a/compiler/fir/analysis-tests/testData/resolve/incorrectDataClass.kt b/compiler/fir/analysis-tests/testData/resolve/incorrectDataClass.kt index 214fca2b270..6936109905b 100644 --- a/compiler/fir/analysis-tests/testData/resolve/incorrectDataClass.kt +++ b/compiler/fir/analysis-tests/testData/resolve/incorrectDataClass.kt @@ -1,5 +1,5 @@ // ISSUE: KT-44554 -data class Foo(a: Int, val b: Int) { +data class Foo(a: Int, val b: Int) { val c = 4 } diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/lambdas/lambdaInWhenBranch.kt b/compiler/fir/analysis-tests/testData/resolve/smartcasts/lambdas/lambdaInWhenBranch.kt index 908142c83af..5dce7808d22 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/lambdas/lambdaInWhenBranch.kt +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/lambdas/lambdaInWhenBranch.kt @@ -4,7 +4,7 @@ private sealed class Sealed private data class SubClass1(val t: String) : Sealed() -private data class SubClass2 : Sealed() +private data class SubClass2 : Sealed() private fun foo(p: Sealed) { when (p) { 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 bd5f099adb9..f92a35b743b 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 @@ -18,7 +18,9 @@ import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol -import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.name.Name @@ -99,9 +101,14 @@ object DIAGNOSTICS_LIST : DiagnosticList() { val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by warning() val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning() - val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by warning() + val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by error() val EXPLICIT_DELEGATION_CALL_REQUIRED by warning(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) val SEALED_CLASS_CONSTRUCTOR_CALL by error() + + // TODO: Consider creating a parameter list position strategy and report on the parameter list instead + val DATA_CLASS_WITHOUT_PARAMETERS by error() + val DATA_CLASS_VARARG_PARAMETER by error() + val DATA_CLASS_NOT_PROPERTY_PARAMETER by error() } val ANNOTATIONS by object : DiagnosticGroup("Annotations") { 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 51d2e38434a..92a9c00b7b4 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 @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.psi.KtModifierListOwner import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.psi.KtPrimaryConstructor import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtPropertyAccessor import org.jetbrains.kotlin.psi.KtPropertyDelegate @@ -104,9 +105,12 @@ object FirErrors { val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning0(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by warning0() val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning0() - val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by warning0() + val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by error0() val EXPLICIT_DELEGATION_CALL_REQUIRED by warning0(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) val SEALED_CLASS_CONSTRUCTOR_CALL by error0() + val DATA_CLASS_WITHOUT_PARAMETERS by error0() + val DATA_CLASS_VARARG_PARAMETER by error0() + val DATA_CLASS_NOT_PROPERTY_PARAMETER by error0() // Annotations val ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR by error0() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt index 692a3749709..fb8b6a1a972 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt @@ -5,24 +5,23 @@ package org.jetbrains.kotlin.fir.analysis.checkers +import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.FirSymbolOwner +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.analysis.cfa.FirReturnsImpliesAnalyzer.isSupertypeOf import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.modalityModifier import org.jetbrains.kotlin.fir.analysis.diagnostics.overrideModifier import org.jetbrains.kotlin.fir.analysis.diagnostics.visibilityModifier -import org.jetbrains.kotlin.fir.containingClass +import org.jetbrains.kotlin.fir.analysis.getChild import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference -import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike @@ -31,11 +30,15 @@ import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol -import org.jetbrains.kotlin.fir.typeContext -import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.ConeClassLikeType +import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtModifierList +import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.psi.KtParameter.VAL_VAR_TOKEN_SET import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -320,3 +323,9 @@ internal fun throwableClassLikeType(session: FirSession) = session.builtinTypes. fun ConeKotlinType.isSubtypeOfThrowable(session: FirSession) = throwableClassLikeType(session).isSupertypeOf(session.typeContext, this.fullyExpandedType(session)) + +val FirValueParameter.hasValOrVar: Boolean + get() { + val source = this.source ?: return false + return source.getChild(VAL_VAR_TOKEN_SET) != null + } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDataClassPrimaryConstructorChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDataClassPrimaryConstructorChecker.kt new file mode 100644 index 00000000000..ff21c1e9b80 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDataClassPrimaryConstructorChecker.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.checkers.declaration + +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.fir.FirFakeSourceElementKind +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.hasValOrVar +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.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.declarations.isData +import org.jetbrains.kotlin.fir.declarations.primaryConstructor + +object FirDataClassPrimaryConstructorChecker : FirRegularClassChecker() { + override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) { + if (declaration.classKind != ClassKind.CLASS || !declaration.isData) { + return + } + + val primaryConstructor = declaration.primaryConstructor + + if (primaryConstructor == null || primaryConstructor.source.let { it == null || it.kind is FirFakeSourceElementKind }) { + reporter.reportOn(declaration.source, FirErrors.PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS, context) + return + } + + val valueParameters = primaryConstructor.valueParameters + if (valueParameters.isEmpty()) { + reporter.reportOn(primaryConstructor.source, FirErrors.DATA_CLASS_WITHOUT_PARAMETERS, context) + } + for (parameter in valueParameters) { + if (parameter.isVararg) { + reporter.reportOn(parameter.source, FirErrors.DATA_CLASS_VARARG_PARAMETER, context) + } + if (!parameter.hasValOrVar) { + reporter.reportOn(parameter.source, FirErrors.DATA_CLASS_NOT_PROPERTY_PARAMETER, context) + } + } + } +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorRequiredForDataClassChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorRequiredForDataClassChecker.kt deleted file mode 100644 index df961f6f436..00000000000 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPrimaryConstructorRequiredForDataClassChecker.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.fir.analysis.checkers.declaration - -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.declarations.FirConstructor -import org.jetbrains.kotlin.fir.declarations.FirRegularClass -import org.jetbrains.kotlin.fir.declarations.isData - -object FirPrimaryConstructorRequiredForDataClassChecker : FirRegularClassChecker() { - override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) { - if (declaration.classKind != ClassKind.CLASS || !declaration.isData) { - return - } - - val hasPrimaryConstructor = declaration.declarations.any { it is FirConstructor && it.isPrimary } - - if (!hasPrimaryConstructor) { - reporter.reportOn(declaration.source, FirErrors.PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS, 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 fa92bb1ed71..a41609378ff 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 @@ -55,6 +55,9 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_IN import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_OBJECT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_INSIDE_INLINE_CLASS +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_NOT_PROPERTY_PARAMETER +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_VARARG_PARAMETER +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_WITHOUT_PARAMETERS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_IN_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_IN_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR @@ -292,6 +295,9 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { "Explicit 'this' or 'super' call is required. There is no constructor in superclass that can be called without arguments" ) map.put(SEALED_CLASS_CONSTRUCTOR_CALL, "Sealed types cannot be instantiated") + map.put(DATA_CLASS_WITHOUT_PARAMETERS, "Data class must have at least one primary constructor parameter") + map.put(DATA_CLASS_VARARG_PARAMETER, "Primary constructor vararg parameters are forbidden for data classes") + map.put(DATA_CLASS_NOT_PROPERTY_PARAMETER, "Data class primary constructor must have only property (val / var) parameters") // Annotations map.put(ANNOTATION_CLASS_MEMBER, "Members are not allowed in annotation class") diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt index c9c59177e8a..580629752c7 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt @@ -55,7 +55,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirLocalEntityNotAllowedChecker, FirManyCompanionObjectsChecker, FirMethodOfAnyImplementedInInterfaceChecker, - FirPrimaryConstructorRequiredForDataClassChecker, + FirDataClassPrimaryConstructorChecker, FirSupertypeInitializedInInterfaceChecker, FirSupertypeInitializedWithoutPrimaryConstructor, FirTypeParametersInObjectChecker, diff --git a/compiler/testData/diagnostics/tests/dataClasses/dataClassNoName.fir.kt b/compiler/testData/diagnostics/tests/dataClasses/dataClassNoName.fir.kt index 4c9bb2fe3c2..99f67431890 100644 --- a/compiler/testData/diagnostics/tests/dataClasses/dataClassNoName.fir.kt +++ b/compiler/testData/diagnostics/tests/dataClasses/dataClassNoName.fir.kt @@ -1,9 +1,9 @@ // See EA-73584 -data class { +data class { -} +} // See KT-9296 data interface { -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/dataClasses/dataClassVarargParam.fir.kt b/compiler/testData/diagnostics/tests/dataClasses/dataClassVarargParam.fir.kt index 394aa100f74..e9a4216042c 100644 --- a/compiler/testData/diagnostics/tests/dataClasses/dataClassVarargParam.fir.kt +++ b/compiler/testData/diagnostics/tests/dataClasses/dataClassVarargParam.fir.kt @@ -1,3 +1,3 @@ -data class My(val x: Int, vararg val y: String) +data class My(val x: Int, vararg val y: String) -data class Your(vararg z: String) \ No newline at end of file +data class Your(vararg z: String) diff --git a/compiler/testData/diagnostics/tests/dataClasses/emptyConstructor.fir.kt b/compiler/testData/diagnostics/tests/dataClasses/emptyConstructor.fir.kt deleted file mode 100644 index ef979927e6d..00000000000 --- a/compiler/testData/diagnostics/tests/dataClasses/emptyConstructor.fir.kt +++ /dev/null @@ -1,6 +0,0 @@ -data class A() - -fun foo(a: A) { - a.component1() - a.component2() -} diff --git a/compiler/testData/diagnostics/tests/dataClasses/emptyConstructor.kt b/compiler/testData/diagnostics/tests/dataClasses/emptyConstructor.kt index e19599657f7..2a07ae8d672 100644 --- a/compiler/testData/diagnostics/tests/dataClasses/emptyConstructor.kt +++ b/compiler/testData/diagnostics/tests/dataClasses/emptyConstructor.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL data class A() fun foo(a: A) { diff --git a/compiler/testData/diagnostics/tests/dataClasses/noConstructor.fir.kt b/compiler/testData/diagnostics/tests/dataClasses/noConstructor.fir.kt index ddaab4d82a9..06c664e8f6e 100644 --- a/compiler/testData/diagnostics/tests/dataClasses/noConstructor.fir.kt +++ b/compiler/testData/diagnostics/tests/dataClasses/noConstructor.fir.kt @@ -1,4 +1,4 @@ -data class A +data class A fun foo(a: A) { a.component1() diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/dataClasses.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/dataClasses.fir.kt index 673c093b93b..8c81f82b4b6 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/dataClasses.fir.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/dataClasses.fir.kt @@ -11,4 +11,4 @@ data class A2(val y: String, val z: Int) { constructor() } -data class A4 internal constructor() +data class A4 internal constructor() diff --git a/compiler/tests-spec/testData/diagnostics/linked/declarations/classifier-declaration/class-declaration/constructor-declaration/p-5/neg/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/declarations/classifier-declaration/class-declaration/constructor-declaration/p-5/neg/1.1.fir.kt index a6887ad20ee..50816995c33 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/declarations/classifier-declaration/class-declaration/constructor-declaration/p-5/neg/1.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/declarations/classifier-declaration/class-declaration/constructor-declaration/p-5/neg/1.1.fir.kt @@ -13,10 +13,10 @@ class Case1() { // TESTCASE NUMBER: 2 class Case2() { - data class A(t: T) - data class B(x: List) - data class C(c: () -> T) - data class E(n: Nothing, t: T) + data class A(t: T) + data class B(x: List) + data class C(c: () -> T) + data class E(n: Nothing, t: T) } // TESTCASE NUMBER: 3 diff --git a/compiler/tests-spec/testData/diagnostics/linked/declarations/classifier-declaration/class-declaration/constructor-declaration/p-5/neg/1.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/declarations/classifier-declaration/class-declaration/constructor-declaration/p-5/neg/1.2.fir.kt index 716a60ad276..8685ab644ab 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/declarations/classifier-declaration/class-declaration/constructor-declaration/p-5/neg/1.2.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/declarations/classifier-declaration/class-declaration/constructor-declaration/p-5/neg/1.2.fir.kt @@ -4,18 +4,18 @@ // TESTCASE NUMBER: 1 -data class A(x: Any?) -data class B(x: Any) -data class C(c: () -> Any) -data class D(e: Enum<*>) -data class E(n: Nothing) -data class F(t: T) +data class A(x: Any?) +data class B(x: Any) +data class C(c: () -> Any) +data class D(e: Enum<*>) +data class E(n: Nothing) +data class F(t: T) // TESTCASE NUMBER: 2 class Case2() { - data class A(t: T) - data class B(x: List) - data class C(c: () -> T) - data class E(n: Nothing, t: T) + data class A(t: T) + data class B(x: List) + data class C(c: () -> T) + data class E(n: Nothing, t: T) } 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 0786cbdffe2..21b46909552 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 @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.KtModifierListOwner import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.psi.KtPrimaryConstructor import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtPropertyAccessor import org.jetbrains.kotlin.psi.KtPropertyDelegate @@ -323,6 +324,24 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.DATA_CLASS_WITHOUT_PARAMETERS) { firDiagnostic -> + DataClassWithoutParametersImpl( + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } + add(FirErrors.DATA_CLASS_VARARG_PARAMETER) { firDiagnostic -> + DataClassVarargParameterImpl( + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } + add(FirErrors.DATA_CLASS_NOT_PROPERTY_PARAMETER) { firDiagnostic -> + DataClassNotPropertyParameterImpl( + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } add(FirErrors.ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR) { firDiagnostic -> AnnotationArgumentKclassLiteralOfTypeParameterErrorImpl( 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 45a709fd005..c8147bfe9cc 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 @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.psi.KtModifierListOwner import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.psi.KtPrimaryConstructor import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtPropertyAccessor import org.jetbrains.kotlin.psi.KtPropertyDelegate @@ -235,6 +236,18 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = SealedClassConstructorCall::class } + abstract class DataClassWithoutParameters : KtFirDiagnostic() { + override val diagnosticClass get() = DataClassWithoutParameters::class + } + + abstract class DataClassVarargParameter : KtFirDiagnostic() { + override val diagnosticClass get() = DataClassVarargParameter::class + } + + abstract class DataClassNotPropertyParameter : KtFirDiagnostic() { + override val diagnosticClass get() = DataClassNotPropertyParameter::class + } + abstract class AnnotationArgumentKclassLiteralOfTypeParameterError : KtFirDiagnostic() { override val diagnosticClass get() = AnnotationArgumentKclassLiteralOfTypeParameterError::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 949de023efa..6dcf6491ca0 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 @@ -32,6 +32,7 @@ import org.jetbrains.kotlin.psi.KtModifierListOwner import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.psi.KtPrimaryConstructor import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtPropertyAccessor import org.jetbrains.kotlin.psi.KtPropertyDelegate @@ -374,6 +375,27 @@ internal class SealedClassConstructorCallImpl( override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) } +internal class DataClassWithoutParametersImpl( + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.DataClassWithoutParameters(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class DataClassVarargParameterImpl( + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.DataClassVarargParameter(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + +internal class DataClassNotPropertyParameterImpl( + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.DataClassNotPropertyParameter(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class AnnotationArgumentKclassLiteralOfTypeParameterErrorImpl( firDiagnostic: FirPsiDiagnostic<*>, override val token: ValidityToken,