FIR: Implement data class constructor checker
This commit is contained in:
committed by
Mikhail Glukhikh
parent
d2da15e039
commit
6e8bad6ef6
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
data class A {}
|
<!PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS!>data class A {}<!>
|
||||||
|
|
||||||
<!PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS!>data class B {
|
<!PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS!>data class B {
|
||||||
constructor()
|
constructor()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// ISSUE: KT-44554
|
// ISSUE: KT-44554
|
||||||
|
|
||||||
data class Foo(a: Int, val b: Int) {
|
data class Foo(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>a: Int<!>, val b: Int) {
|
||||||
val c = 4
|
val c = 4
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
private sealed class Sealed
|
private sealed class Sealed
|
||||||
|
|
||||||
private data class SubClass1(val t: String) : Sealed()
|
private data class SubClass1(val t: String) : Sealed()
|
||||||
private data class SubClass2 : Sealed()
|
<!PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS!>private data class SubClass2 : Sealed()<!>
|
||||||
|
|
||||||
private fun foo(p: Sealed) {
|
private fun foo(p: Sealed) {
|
||||||
when (p) {
|
when (p) {
|
||||||
|
|||||||
+9
-2
@@ -18,7 +18,9 @@ import org.jetbrains.kotlin.fir.declarations.FirClass
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
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.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -99,9 +101,14 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
|
|||||||
val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning<FirSourceElement, PsiElement>(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
|
val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning<FirSourceElement, PsiElement>(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
|
||||||
val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by warning<FirSourceElement, PsiElement>()
|
val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by warning<FirSourceElement, PsiElement>()
|
||||||
val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning<FirSourceElement, PsiElement>()
|
val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning<FirSourceElement, PsiElement>()
|
||||||
val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by warning<FirSourceElement, PsiElement>()
|
val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by error<FirSourceElement, PsiElement>()
|
||||||
val EXPLICIT_DELEGATION_CALL_REQUIRED by warning<FirSourceElement, PsiElement>(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
|
val EXPLICIT_DELEGATION_CALL_REQUIRED by warning<FirSourceElement, PsiElement>(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
|
||||||
val SEALED_CLASS_CONSTRUCTOR_CALL by error<FirSourceElement, PsiElement>()
|
val SEALED_CLASS_CONSTRUCTOR_CALL by error<FirSourceElement, PsiElement>()
|
||||||
|
|
||||||
|
// TODO: Consider creating a parameter list position strategy and report on the parameter list instead
|
||||||
|
val DATA_CLASS_WITHOUT_PARAMETERS by error<FirSourceElement, KtPrimaryConstructor>()
|
||||||
|
val DATA_CLASS_VARARG_PARAMETER by error<FirSourceElement, KtParameter>()
|
||||||
|
val DATA_CLASS_NOT_PROPERTY_PARAMETER by error<FirSourceElement, KtParameter>()
|
||||||
}
|
}
|
||||||
|
|
||||||
val ANNOTATIONS by object : DiagnosticGroup("Annotations") {
|
val ANNOTATIONS by object : DiagnosticGroup("Annotations") {
|
||||||
|
|||||||
+5
-1
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.psi.KtModifierListOwner
|
|||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtParameter
|
import org.jetbrains.kotlin.psi.KtParameter
|
||||||
|
import org.jetbrains.kotlin.psi.KtPrimaryConstructor
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||||
@@ -104,9 +105,12 @@ object FirErrors {
|
|||||||
val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning0<FirSourceElement, PsiElement>(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
|
val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning0<FirSourceElement, PsiElement>(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
|
||||||
val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by warning0<FirSourceElement, PsiElement>()
|
val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by warning0<FirSourceElement, PsiElement>()
|
||||||
val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning0<FirSourceElement, PsiElement>()
|
val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning0<FirSourceElement, PsiElement>()
|
||||||
val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by warning0<FirSourceElement, PsiElement>()
|
val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by error0<FirSourceElement, PsiElement>()
|
||||||
val EXPLICIT_DELEGATION_CALL_REQUIRED by warning0<FirSourceElement, PsiElement>(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
|
val EXPLICIT_DELEGATION_CALL_REQUIRED by warning0<FirSourceElement, PsiElement>(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
|
||||||
val SEALED_CLASS_CONSTRUCTOR_CALL by error0<FirSourceElement, PsiElement>()
|
val SEALED_CLASS_CONSTRUCTOR_CALL by error0<FirSourceElement, PsiElement>()
|
||||||
|
val DATA_CLASS_WITHOUT_PARAMETERS by error0<FirSourceElement, KtPrimaryConstructor>()
|
||||||
|
val DATA_CLASS_VARARG_PARAMETER by error0<FirSourceElement, KtParameter>()
|
||||||
|
val DATA_CLASS_NOT_PROPERTY_PARAMETER by error0<FirSourceElement, KtParameter>()
|
||||||
|
|
||||||
// Annotations
|
// Annotations
|
||||||
val ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR by error0<FirSourceElement, KtExpression>()
|
val ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR by error0<FirSourceElement, KtExpression>()
|
||||||
|
|||||||
@@ -5,24 +5,23 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.checkers
|
package org.jetbrains.kotlin.fir.analysis.checkers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.FirSymbolOwner
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.cfa.FirReturnsImpliesAnalyzer.isSupertypeOf
|
import org.jetbrains.kotlin.fir.analysis.cfa.FirReturnsImpliesAnalyzer.isSupertypeOf
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.modalityModifier
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.modalityModifier
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.overrideModifier
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.overrideModifier
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.visibilityModifier
|
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.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock
|
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
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.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike
|
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.scopes.unsubstitutedScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
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.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.KtModifierList
|
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.psi.psiUtil.visibilityModifierType
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
@@ -320,3 +323,9 @@ internal fun throwableClassLikeType(session: FirSession) = session.builtinTypes.
|
|||||||
|
|
||||||
fun ConeKotlinType.isSubtypeOfThrowable(session: FirSession) =
|
fun ConeKotlinType.isSubtypeOfThrowable(session: FirSession) =
|
||||||
throwableClassLikeType(session).isSupertypeOf(session.typeContext, this.fullyExpandedType(session))
|
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
|
||||||
|
}
|
||||||
|
|||||||
+45
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
-29
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+6
@@ -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.CONSTRUCTOR_IN_OBJECT
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL
|
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.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.DELEGATED_PROPERTY_IN_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_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
|
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"
|
"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(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
|
// Annotations
|
||||||
map.put(ANNOTATION_CLASS_MEMBER, "Members are not allowed in annotation class")
|
map.put(ANNOTATION_CLASS_MEMBER, "Members are not allowed in annotation class")
|
||||||
|
|||||||
+1
-1
@@ -55,7 +55,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
|||||||
FirLocalEntityNotAllowedChecker,
|
FirLocalEntityNotAllowedChecker,
|
||||||
FirManyCompanionObjectsChecker,
|
FirManyCompanionObjectsChecker,
|
||||||
FirMethodOfAnyImplementedInInterfaceChecker,
|
FirMethodOfAnyImplementedInInterfaceChecker,
|
||||||
FirPrimaryConstructorRequiredForDataClassChecker,
|
FirDataClassPrimaryConstructorChecker,
|
||||||
FirSupertypeInitializedInInterfaceChecker,
|
FirSupertypeInitializedInInterfaceChecker,
|
||||||
FirSupertypeInitializedWithoutPrimaryConstructor,
|
FirSupertypeInitializedWithoutPrimaryConstructor,
|
||||||
FirTypeParametersInObjectChecker,
|
FirTypeParametersInObjectChecker,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// See EA-73584
|
// See EA-73584
|
||||||
data class<!SYNTAX!><!> {
|
<!PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS!>data class<!SYNTAX!><!> {
|
||||||
|
|
||||||
}
|
}<!>
|
||||||
|
|
||||||
// See KT-9296
|
// See KT-9296
|
||||||
data interface<!SYNTAX!><!> {
|
data interface<!SYNTAX!><!> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
data class My(val x: Int, vararg val y: String)
|
data class My(val x: Int, <!DATA_CLASS_VARARG_PARAMETER!>vararg val y: String<!>)
|
||||||
|
|
||||||
data class Your(vararg z: String)
|
data class Your(<!DATA_CLASS_NOT_PROPERTY_PARAMETER, DATA_CLASS_VARARG_PARAMETER!>vararg z: String<!>)
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
data class A()
|
|
||||||
|
|
||||||
fun foo(a: A) {
|
|
||||||
a.<!UNRESOLVED_REFERENCE!>component1<!>()
|
|
||||||
a.<!UNRESOLVED_REFERENCE!>component2<!>()
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
data class A<!DATA_CLASS_WITHOUT_PARAMETERS!>()<!>
|
data class A<!DATA_CLASS_WITHOUT_PARAMETERS!>()<!>
|
||||||
|
|
||||||
fun foo(a: A) {
|
fun foo(a: A) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
data class A
|
<!PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS!>data class A<!>
|
||||||
|
|
||||||
fun foo(a: A) {
|
fun foo(a: A) {
|
||||||
a.<!UNRESOLVED_REFERENCE!>component1<!>()
|
a.<!UNRESOLVED_REFERENCE!>component1<!>()
|
||||||
|
|||||||
+1
-1
@@ -11,4 +11,4 @@ data class A2(val y: String, val z: Int) {
|
|||||||
constructor()
|
constructor()
|
||||||
}<!>
|
}<!>
|
||||||
|
|
||||||
data class A4 internal constructor()
|
data class A4 <!DATA_CLASS_WITHOUT_PARAMETERS!>internal constructor()<!>
|
||||||
|
|||||||
+4
-4
@@ -13,10 +13,10 @@ class Case1<T>() {
|
|||||||
|
|
||||||
// TESTCASE NUMBER: 2
|
// TESTCASE NUMBER: 2
|
||||||
class Case2<T>() {
|
class Case2<T>() {
|
||||||
data class A(t: T)
|
data class A(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>t: T<!>)
|
||||||
data class B(x: List<T>)
|
data class B(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>x: List<T><!>)
|
||||||
data class C(c: () -> T)
|
data class C(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>c: () -> T<!>)
|
||||||
data class E(n: Nothing, t: T)
|
data class E(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>n: Nothing<!>, <!DATA_CLASS_NOT_PROPERTY_PARAMETER!>t: T<!>)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 3
|
// TESTCASE NUMBER: 3
|
||||||
|
|||||||
+10
-10
@@ -4,18 +4,18 @@
|
|||||||
|
|
||||||
|
|
||||||
// TESTCASE NUMBER: 1
|
// TESTCASE NUMBER: 1
|
||||||
data class A(x: Any?)
|
data class A(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>x: Any?<!>)
|
||||||
data class B(x: Any)
|
data class B(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>x: Any<!>)
|
||||||
data class C(c: () -> Any)
|
data class C(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>c: () -> Any<!>)
|
||||||
data class D(e: Enum<*>)
|
data class D(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>e: Enum<*><!>)
|
||||||
data class E(n: Nothing)
|
data class E(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>n: Nothing<!>)
|
||||||
data class F<T>(t: T)
|
data class F<T>(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>t: T<!>)
|
||||||
|
|
||||||
|
|
||||||
// TESTCASE NUMBER: 2
|
// TESTCASE NUMBER: 2
|
||||||
class Case2<T>() {
|
class Case2<T>() {
|
||||||
data class A(t: T)
|
data class A(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>t: T<!>)
|
||||||
data class B(x: List<T>)
|
data class B(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>x: List<T><!>)
|
||||||
data class C(c: () -> T)
|
data class C(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>c: () -> T<!>)
|
||||||
data class E(n: Nothing, t: T)
|
data class E(<!DATA_CLASS_NOT_PROPERTY_PARAMETER!>n: Nothing<!>, <!DATA_CLASS_NOT_PROPERTY_PARAMETER!>t: T<!>)
|
||||||
}
|
}
|
||||||
|
|||||||
+19
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.KtModifierListOwner
|
|||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtParameter
|
import org.jetbrains.kotlin.psi.KtParameter
|
||||||
|
import org.jetbrains.kotlin.psi.KtPrimaryConstructor
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||||
@@ -323,6 +324,24 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
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 ->
|
add(FirErrors.ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR) { firDiagnostic ->
|
||||||
AnnotationArgumentKclassLiteralOfTypeParameterErrorImpl(
|
AnnotationArgumentKclassLiteralOfTypeParameterErrorImpl(
|
||||||
firDiagnostic as FirPsiDiagnostic<*>,
|
firDiagnostic as FirPsiDiagnostic<*>,
|
||||||
|
|||||||
+13
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.psi.KtModifierListOwner
|
|||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtParameter
|
import org.jetbrains.kotlin.psi.KtParameter
|
||||||
|
import org.jetbrains.kotlin.psi.KtPrimaryConstructor
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||||
@@ -235,6 +236,18 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = SealedClassConstructorCall::class
|
override val diagnosticClass get() = SealedClassConstructorCall::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class DataClassWithoutParameters : KtFirDiagnostic<KtPrimaryConstructor>() {
|
||||||
|
override val diagnosticClass get() = DataClassWithoutParameters::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class DataClassVarargParameter : KtFirDiagnostic<KtParameter>() {
|
||||||
|
override val diagnosticClass get() = DataClassVarargParameter::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class DataClassNotPropertyParameter : KtFirDiagnostic<KtParameter>() {
|
||||||
|
override val diagnosticClass get() = DataClassNotPropertyParameter::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class AnnotationArgumentKclassLiteralOfTypeParameterError : KtFirDiagnostic<KtExpression>() {
|
abstract class AnnotationArgumentKclassLiteralOfTypeParameterError : KtFirDiagnostic<KtExpression>() {
|
||||||
override val diagnosticClass get() = AnnotationArgumentKclassLiteralOfTypeParameterError::class
|
override val diagnosticClass get() = AnnotationArgumentKclassLiteralOfTypeParameterError::class
|
||||||
}
|
}
|
||||||
|
|||||||
+22
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.psi.KtModifierListOwner
|
|||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtParameter
|
import org.jetbrains.kotlin.psi.KtParameter
|
||||||
|
import org.jetbrains.kotlin.psi.KtPrimaryConstructor
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||||
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
import org.jetbrains.kotlin.psi.KtPropertyDelegate
|
||||||
@@ -374,6 +375,27 @@ internal class SealedClassConstructorCallImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class DataClassWithoutParametersImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.DataClassWithoutParameters(), KtAbstractFirDiagnostic<KtPrimaryConstructor> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class DataClassVarargParameterImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.DataClassVarargParameter(), KtAbstractFirDiagnostic<KtParameter> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class DataClassNotPropertyParameterImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.DataClassNotPropertyParameter(), KtAbstractFirDiagnostic<KtParameter> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class AnnotationArgumentKclassLiteralOfTypeParameterErrorImpl(
|
internal class AnnotationArgumentKclassLiteralOfTypeParameterErrorImpl(
|
||||||
firDiagnostic: FirPsiDiagnostic<*>,
|
firDiagnostic: FirPsiDiagnostic<*>,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
|
|||||||
Reference in New Issue
Block a user