[FIR] Add check of abstractness and existence of receiver parameters for lateinit var; add lacking lateinit modifier

#KT-59973
This commit is contained in:
Evgeniy.Zhelenskiy
2023-10-25 06:26:31 +02:00
committed by Space Team
parent e789e08fb7
commit 6a5b356d30
5 changed files with 19 additions and 73 deletions
@@ -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"
@@ -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 {
@@ -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
@@ -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<T: Any, V: String?>(lateinit var p2: String) {
public <!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> val a: String
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> val b: T
private lateinit var c: CharSequence
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> val d: String
get
public lateinit var e: String
get
private set
fun a() {
lateinit var a: String
}
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var e1: V
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var e2: String?
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var e3: Int
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var e4: Int?
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var e5 = "A"
// With initializer, primitive
<!INAPPLICABLE_LATEINIT_MODIFIER, INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var e6 = 3
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var e7 by CustomDelegate()
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var e8: String
get() = "A"
<!INAPPLICABLE_LATEINIT_MODIFIER!>lateinit<!> var e9: String
set(v) { field = v }
abstract lateinit var e10: String
lateinit var String.e11: String
lateinit var String.e12: String
}
<!INAPPLICABLE_LATEINIT_MODIFIER!>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
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +LateinitTopLevelProperties +LateinitLocalVariables
import kotlin.reflect.KProperty