[FIR] Add check of abstractness and existence of receiver parameters for lateinit var; add lacking lateinit modifier
#KT-59973
This commit is contained in:
committed by
Space Team
parent
e789e08fb7
commit
6a5b356d30
+14
@@ -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.FirDefaultPropertyGetter
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.hasExplicitBackingField
|
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.declarations.utils.isLateInit
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
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)
|
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)) {
|
if (declaration.returnTypeRef.coneType.isSingleFieldValueClass(context.session)) {
|
||||||
val declarationType = declaration.returnTypeRef.coneType
|
val declarationType = declaration.returnTypeRef.coneType
|
||||||
val variables = if (declaration.isLocal) "local variables" else "properties"
|
val variables = if (declaration.isLocal) "local variables" else "properties"
|
||||||
|
|||||||
+2
-1
@@ -137,6 +137,7 @@ class ValueParameter(
|
|||||||
isActual = modifiers.hasActual()
|
isActual = modifiers.hasActual()
|
||||||
isOverride = modifiers.hasOverride()
|
isOverride = modifiers.hasOverride()
|
||||||
isConst = modifiers.hasConst()
|
isConst = modifiers.hasConst()
|
||||||
|
isLateInit = modifiers.hasLateinit()
|
||||||
}
|
}
|
||||||
|
|
||||||
val defaultAccessorSource = propertySource?.fakeElement(KtFakeSourceElementKind.DefaultAccessor)
|
val defaultAccessorSource = propertySource?.fakeElement(KtFakeSourceElementKind.DefaultAccessor)
|
||||||
@@ -150,7 +151,7 @@ class ValueParameter(
|
|||||||
returnTypeRef = returnTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.DefaultAccessor),
|
returnTypeRef = returnTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.DefaultAccessor),
|
||||||
isVar = isVar,
|
isVar = isVar,
|
||||||
propertySymbol = symbol,
|
propertySymbol = symbol,
|
||||||
status = status.copy(),
|
status = status.copy(isLateInit = false),
|
||||||
)
|
)
|
||||||
|
|
||||||
annotations += modifiers.annotations.filter {
|
annotations += modifiers.annotations.filter {
|
||||||
|
|||||||
+2
-1
@@ -687,6 +687,7 @@ open class PsiRawFirBuilder(
|
|||||||
isActual = hasActualModifier()
|
isActual = hasActualModifier()
|
||||||
isOverride = hasModifier(OVERRIDE_KEYWORD)
|
isOverride = hasModifier(OVERRIDE_KEYWORD)
|
||||||
isConst = hasModifier(CONST_KEYWORD)
|
isConst = hasModifier(CONST_KEYWORD)
|
||||||
|
isLateInit = hasModifier(LATEINIT_KEYWORD)
|
||||||
}
|
}
|
||||||
|
|
||||||
val propertySource = toFirSourceElement(KtFakeSourceElementKind.PropertyFromParameter)
|
val propertySource = toFirSourceElement(KtFakeSourceElementKind.PropertyFromParameter)
|
||||||
@@ -732,7 +733,7 @@ open class PsiRawFirBuilder(
|
|||||||
returnTypeRef = returnTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.DefaultAccessor),
|
returnTypeRef = returnTypeRef.copyWithNewSourceKind(KtFakeSourceElementKind.DefaultAccessor),
|
||||||
isVar = isVar,
|
isVar = isVar,
|
||||||
propertySymbol = symbol,
|
propertySymbol = symbol,
|
||||||
status = status.copy(),
|
status = status.copy(isLateInit = false),
|
||||||
)
|
)
|
||||||
|
|
||||||
this.status = status
|
this.status = status
|
||||||
|
|||||||
-71
@@ -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
|
// !LANGUAGE: +LateinitTopLevelProperties +LateinitLocalVariables
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user