[FIR] KT-59421 add checker context receiver property backing field

This commit is contained in:
Tomas Husak
2023-12-06 15:35:43 +01:00
committed by Space Team
parent 6c3b740a05
commit 91465d7110
11 changed files with 54 additions and 17 deletions
@@ -2111,6 +2111,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.CONTEXT_RECEIVERS_WITH_BACKING_FIELD) { firDiagnostic ->
ContextReceiversWithBackingFieldImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.RECURSION_IN_IMPLICIT_TYPES) { firDiagnostic ->
RecursionInImplicitTypesImpl(
firDiagnostic as KtPsiDiagnostic,
@@ -1504,6 +1504,10 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = SubtypingBetweenContextReceivers::class
}
interface ContextReceiversWithBackingField : KtFirDiagnostic<KtElement> {
override val diagnosticClass get() = ContextReceiversWithBackingField::class
}
interface RecursionInImplicitTypes : KtFirDiagnostic<PsiElement> {
override val diagnosticClass get() = RecursionInImplicitTypes::class
}
@@ -1805,6 +1805,11 @@ internal class SubtypingBetweenContextReceiversImpl(
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtElement>(firDiagnostic, token), KtFirDiagnostic.SubtypingBetweenContextReceivers
internal class ContextReceiversWithBackingFieldImpl(
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
) : KtAbstractFirDiagnostic<KtElement>(firDiagnostic, token), KtFirDiagnostic.ContextReceiversWithBackingField
internal class RecursionInImplicitTypesImpl(
firDiagnostic: KtPsiDiagnostic,
token: KtLifetimeToken,
@@ -676,6 +676,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val AMBIGUOUS_CALL_WITH_IMPLICIT_CONTEXT_RECEIVER by error<KtElement>(PositioningStrategy.REFERENCE_BY_QUALIFIED)
val UNSUPPORTED_CONTEXTUAL_DECLARATION_CALL by error<KtElement>(PositioningStrategy.NAME_IDENTIFIER)
val SUBTYPING_BETWEEN_CONTEXT_RECEIVERS by error<KtElement>(PositioningStrategy.DEFAULT)
val CONTEXT_RECEIVERS_WITH_BACKING_FIELD by error<KtElement>(PositioningStrategy.DEFAULT)
}
val TYPES_AND_TYPE_PARAMETERS by object : DiagnosticGroup("Types & type parameters") {
@@ -425,6 +425,7 @@ object FirErrors {
val AMBIGUOUS_CALL_WITH_IMPLICIT_CONTEXT_RECEIVER: KtDiagnosticFactory0 by error0<KtElement>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
val UNSUPPORTED_CONTEXTUAL_DECLARATION_CALL: KtDiagnosticFactory0 by error0<KtElement>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val SUBTYPING_BETWEEN_CONTEXT_RECEIVERS: KtDiagnosticFactory0 by error0<KtElement>()
val CONTEXT_RECEIVERS_WITH_BACKING_FIELD: KtDiagnosticFactory0 by error0<KtElement>()
// Types & type parameters
val RECURSION_IN_IMPLICIT_TYPES: KtDiagnosticFactory0 by error0<PsiElement>()
@@ -264,6 +264,7 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set<String> = setOf(
"AMBIGUOUS_CALL_WITH_IMPLICIT_CONTEXT_RECEIVER",
"UNSUPPORTED_CONTEXTUAL_DECLARATION_CALL",
"SUBTYPING_BETWEEN_CONTEXT_RECEIVERS",
"CONTEXT_RECEIVERS_WITH_BACKING_FIELD",
"RECURSION_IN_IMPLICIT_TYPES",
"INFERENCE_ERROR",
"PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT",
@@ -91,6 +91,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
ContractSyntaxV2PropertyChecker,
FirVolatileAnnotationChecker,
FirInlinePropertyChecker,
FirContextReceiversPropertyBackingFieldChecker
)
override val backingFieldCheckers: Set<FirBackingFieldChecker>
@@ -0,0 +1,29 @@
/*
* Copyright 2010-2023 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.config.LanguageFeature
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField
object FirContextReceiversPropertyBackingFieldChecker : FirPropertyChecker() {
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.ContextReceivers)) return
if (declaration.contextReceivers.isEmpty()) return
if (declaration.hasBackingField) {
reporter.reportOn(
declaration.initializer?.source,
FirErrors.CONTEXT_RECEIVERS_WITH_BACKING_FIELD,
context
)
}
}
}
@@ -154,6 +154,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONST_VAL_WITHOUT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONST_VAL_WITH_DELEGATE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONST_VAL_WITH_GETTER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONST_VAL_WITH_NON_CONST_INITIALIZER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONTEXT_RECEIVERS_WITH_BACKING_FIELD
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONTRACT_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLE_IN_ANNOTATION_PARAMETER
@@ -1282,6 +1283,10 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
SUBTYPING_BETWEEN_CONTEXT_RECEIVERS,
"Subtyping relation between context receivers is prohibited."
)
map.put(
CONTEXT_RECEIVERS_WITH_BACKING_FIELD,
"Property with context receivers cannot be initialized because it has no backing field."
)
// Ambiguity
map.put(OVERLOAD_RESOLUTION_AMBIGUITY, "Overload resolution ambiguity between candidates: {0}", SYMBOLS)
@@ -1,17 +0,0 @@
// !LANGUAGE: +ContextReceivers
interface A {
fun a(): Int
}
interface B {
fun b(): Int
}
context(A)
val a = 1
context(A, B)
var b = 2
context(A, B)
val c get() = a() + b()
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +ContextReceivers
interface A {