[FIR] Do not allow context receivers on value classes

#KT-59413 Fixed
This commit is contained in:
Brian Norman
2023-06-27 16:49:22 +03:00
committed by Space Team
parent b74ff19930
commit 61acd2b6f5
8 changed files with 30 additions and 8 deletions
@@ -1646,6 +1646,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.VALUE_CLASS_CANNOT_HAVE_CONTEXT_RECEIVERS) { firDiagnostic ->
ValueClassCannotHaveContextReceiversImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.ANNOTATION_ON_ILLEGAL_MULTI_FIELD_VALUE_CLASS_TYPED_TARGET) { firDiagnostic ->
AnnotationOnIllegalMultiFieldValueClassTypedTargetImpl(
firDiagnostic.a,
@@ -1182,6 +1182,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = ValueClassCannotBeCloneable::class
}
interface ValueClassCannotHaveContextReceivers : KtFirDiagnostic<KtDeclaration> {
override val diagnosticClass get() = ValueClassCannotHaveContextReceivers::class
}
interface AnnotationOnIllegalMultiFieldValueClassTypedTarget : KtFirDiagnostic<KtAnnotationEntry> {
override val diagnosticClass get() = AnnotationOnIllegalMultiFieldValueClassTypedTarget::class
val name: String
@@ -1419,6 +1419,11 @@ internal class ValueClassCannotBeCloneableImpl(
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtDeclaration>(firDiagnostic, token), KtFirDiagnostic.ValueClassCannotBeCloneable
internal class ValueClassCannotHaveContextReceiversImpl(
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtDeclaration>(firDiagnostic, token), KtFirDiagnostic.ValueClassCannotHaveContextReceivers
internal class AnnotationOnIllegalMultiFieldValueClassTypedTargetImpl(
override val name: String,
firDiagnostic: KtPsiDiagnostic,
@@ -490,6 +490,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val TYPE_ARGUMENT_ON_TYPED_VALUE_CLASS_EQUALS by error<KtTypeReference>()
val INNER_CLASS_INSIDE_VALUE_CLASS by error<KtDeclaration>(PositioningStrategy.INNER_MODIFIER)
val VALUE_CLASS_CANNOT_BE_CLONEABLE by error<KtDeclaration>(PositioningStrategy.INLINE_OR_VALUE_MODIFIER)
val VALUE_CLASS_CANNOT_HAVE_CONTEXT_RECEIVERS by error<KtDeclaration>()
val ANNOTATION_ON_ILLEGAL_MULTI_FIELD_VALUE_CLASS_TYPED_TARGET by error<KtAnnotationEntry> {
parameter<String>("name")
}
@@ -349,6 +349,7 @@ object FirErrors {
val TYPE_ARGUMENT_ON_TYPED_VALUE_CLASS_EQUALS by error0<KtTypeReference>()
val INNER_CLASS_INSIDE_VALUE_CLASS by error0<KtDeclaration>(SourceElementPositioningStrategies.INNER_MODIFIER)
val VALUE_CLASS_CANNOT_BE_CLONEABLE by error0<KtDeclaration>(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER)
val VALUE_CLASS_CANNOT_HAVE_CONTEXT_RECEIVERS by error0<KtDeclaration>()
val ANNOTATION_ON_ILLEGAL_MULTI_FIELD_VALUE_CLASS_TYPED_TARGET by error1<KtAnnotationEntry, String>()
// Applicability
@@ -53,7 +53,10 @@ object FirValueClassDeclarationChecker : FirRegularClassChecker() {
reporter.reportOn(declaration.source, FirErrors.VALUE_CLASS_NOT_FINAL, context)
}
// TODO check absence of context receivers when FIR infrastructure is ready
if (declaration.contextReceivers.isNotEmpty()) {
reporter.reportOn(declaration.source, FirErrors.VALUE_CLASS_CANNOT_HAVE_CONTEXT_RECEIVERS, context)
}
for (supertypeEntry in declaration.superTypeRefs) {
if (supertypeEntry !is FirImplicitAnyTypeRef && supertypeEntry.toRegularClassSymbol(context.session)?.isInterface != true) {
@@ -206,7 +209,7 @@ object FirValueClassDeclarationChecker : FirRegularClassChecker() {
}
declaration.multiFieldValueClassRepresentation != null && primaryConstructorParameter.defaultValue != null -> {
// todo fix when inline arguments are supported
// TODO, KT-50113: Fix when inline arguments are supported.
reporter.reportOn(
primaryConstructorParameter.defaultValue!!.source,
FirErrors.MULTI_FIELD_VALUE_CLASS_PRIMARY_CONSTRUCTOR_DEFAULT_PARAMETER,
@@ -601,6 +601,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_RECURSIVE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_EXTEND_CLASSES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_HAVE_CONTEXT_RECEIVERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_EMPTY_CONSTRUCTOR
@@ -1382,6 +1383,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
map.put(TYPE_ARGUMENT_ON_TYPED_VALUE_CLASS_EQUALS, "Type arguments for typed value class equals must all be star projections")
map.put(INNER_CLASS_INSIDE_VALUE_CLASS, "Value class cannot have inner classes")
map.put(VALUE_CLASS_CANNOT_BE_CLONEABLE, "Value class cannot be Cloneable")
map.put(VALUE_CLASS_CANNOT_HAVE_CONTEXT_RECEIVERS, "Value classes cannot have context receivers")
map.put(
ANNOTATION_ON_ILLEGAL_MULTI_FIELD_VALUE_CLASS_TYPED_TARGET,
"Annotations on ''{0}'' of multi-field value class type are not supported",
@@ -7,13 +7,13 @@
class A
context(A)
inline class B1(val x: Int)
<!VALUE_CLASS_CANNOT_HAVE_CONTEXT_RECEIVERS!>context(A)
inline class B1(val x: Int)<!>
context(A)
<!VALUE_CLASS_CANNOT_HAVE_CONTEXT_RECEIVERS!>context(A)
OPTIONAL_JVM_INLINE_ANNOTATION
value class B2(val x: Int)
value class B2(val x: Int)<!>
context(A)
<!VALUE_CLASS_CANNOT_HAVE_CONTEXT_RECEIVERS!>context(A)
OPTIONAL_JVM_INLINE_ANNOTATION
value class C(val x: Int, val y: Int)
value class C(val x: Int, val y: Int)<!>