diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInapplicableLateinitChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInapplicableLateinitChecker.kt index 4c5caf40b59..6816db4ab9e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInapplicableLateinitChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInapplicableLateinitChecker.kt @@ -19,6 +19,8 @@ import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter import org.jetbrains.kotlin.fir.declarations.utils.hasExplicitBackingField +import org.jetbrains.kotlin.fir.declarations.utils.isAbstract +import org.jetbrains.kotlin.fir.declarations.utils.isExtension import org.jetbrains.kotlin.fir.declarations.utils.isLateInit import org.jetbrains.kotlin.fir.types.* @@ -64,6 +66,18 @@ object FirInapplicableLateinitChecker : FirPropertyChecker() { reporter.reportError(declaration.source, "is not allowed on properties with a custom getter or setter", context) } + if (declaration.isExtension) { + reporter.reportError(declaration.source, "is not allowed on extension properties", context) + } + + if (declaration.contextReceivers.isNotEmpty()) { + reporter.reportError(declaration.source, "is not allowed on properties with context receivers", context) + } + + if (declaration.isAbstract) { + reporter.reportError(declaration.source, "is not allowed on abstract properties", context) + } + if (declaration.returnTypeRef.coneType.isSingleFieldValueClass(context.session)) { val declarationType = declaration.returnTypeRef.coneType val variables = if (declaration.isLocal) "local variables" else "properties" diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt index 3e96c6ccfcb..d72f4e27db2 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/fir/ValueParameter.kt @@ -137,6 +137,7 @@ class ValueParameter( isActual = modifiers.hasActual() isOverride = modifiers.hasOverride() isConst = modifiers.hasConst() + isLateInit = modifiers.hasLateinit() } val defaultAccessorSource = propertySource?.fakeElement(KtFakeSourceElementKind.DefaultAccessor) @@ -150,7 +151,7 @@ class ValueParameter( returnTypeRef = returnTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.DefaultAccessor), isVar = isVar, propertySymbol = symbol, - status = status.copy(), + status = status.copy(isLateInit = false), ) annotations += modifiers.annotations.filter { diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt index 50c09b46aab..50560616097 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/PsiRawFirBuilder.kt @@ -687,6 +687,7 @@ open class PsiRawFirBuilder( isActual = hasActualModifier() isOverride = hasModifier(OVERRIDE_KEYWORD) isConst = hasModifier(CONST_KEYWORD) + isLateInit = hasModifier(LATEINIT_KEYWORD) } val propertySource = toFirSourceElement(KtFakeSourceElementKind.PropertyFromParameter) @@ -732,7 +733,7 @@ open class PsiRawFirBuilder( returnTypeRef = returnTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.DefaultAccessor), isVar = isVar, propertySymbol = symbol, - status = status.copy(), + status = status.copy(isLateInit = false), ) this.status = status diff --git a/compiler/testData/diagnostics/tests/lateinit/modifierApplicability_lv12.fir.kt b/compiler/testData/diagnostics/tests/lateinit/modifierApplicability_lv12.fir.kt deleted file mode 100644 index df4efef4a49..00000000000 --- a/compiler/testData/diagnostics/tests/lateinit/modifierApplicability_lv12.fir.kt +++ /dev/null @@ -1,71 +0,0 @@ -// !LANGUAGE: +LateinitTopLevelProperties +LateinitLocalVariables -import kotlin.reflect.KProperty - -class CustomDelegate { - operator fun getValue(thisRef: Any?, prop: KProperty<*>): String = prop.name - operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: String) {} -} - -public abstract class A(lateinit var p2: String) { - - public lateinit val a: String - lateinit val b: T - private lateinit var c: CharSequence - - lateinit val d: String - get - - public lateinit var e: String - get - private set - - fun a() { - lateinit var a: String - } - - lateinit var e1: V - lateinit var e2: String? - lateinit var e3: Int - lateinit var e4: Int? - lateinit var e5 = "A" - - // With initializer, primitive - lateinit var e6 = 3 - - lateinit var e7 by CustomDelegate() - - lateinit var e8: String - get() = "A" - - lateinit var e9: String - set(v) { field = v } - - abstract lateinit var e10: String - - lateinit var String.e11: String - - lateinit var String.e12: String -} - -lateinit val topLevel: String -lateinit var topLevelMutable: String - -public interface Intf { - lateinit var str: String -} - -public abstract class AbstractClass { - abstract var str: String -} - -public class AbstractClassImpl : AbstractClass() { - override lateinit var str: String -} - -public class B { - lateinit var a: String - - init { - a.length - } -} diff --git a/compiler/testData/diagnostics/tests/lateinit/modifierApplicability_lv12.kt b/compiler/testData/diagnostics/tests/lateinit/modifierApplicability_lv12.kt index 790bb891756..3f009bf907c 100644 --- a/compiler/testData/diagnostics/tests/lateinit/modifierApplicability_lv12.kt +++ b/compiler/testData/diagnostics/tests/lateinit/modifierApplicability_lv12.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +LateinitTopLevelProperties +LateinitLocalVariables import kotlin.reflect.KProperty