[FIR] fix false negative MUST_BE_INITIALIZED for deferred init + custom setter case
^KT-58346 Fixed Review: https://jetbrains.team/p/kt/reviews/9967 BTW this commit accidentaly and partially fixes KT-57553 for K2, because of a cleaner K2 architecture. I will unify MUST_BE_INITIALIZED behaviour in K1 and K2 in the next commits
This commit is contained in:
+4
-4
@@ -35,8 +35,8 @@ object FirMemberPropertiesChecker : FirClassChecker() {
|
||||
for (innerDeclaration in declaration.declarations) {
|
||||
if (innerDeclaration is FirProperty) {
|
||||
val symbol = innerDeclaration.symbol
|
||||
val isInitialized = innerDeclaration.initializer != null || info?.get(symbol)?.isDefinitelyVisited() == true
|
||||
checkProperty(declaration, innerDeclaration, isInitialized, context, reporter, !reachedDeadEnd)
|
||||
val isDefinitelyAssignedInConstructor = info?.get(symbol)?.isDefinitelyVisited() == true
|
||||
checkProperty(declaration, innerDeclaration, isDefinitelyAssignedInConstructor, context, reporter, !reachedDeadEnd)
|
||||
}
|
||||
// Can't just look at each property's graph's enterNode because they may have no graph if there is no initializer.
|
||||
reachedDeadEnd = reachedDeadEnd ||
|
||||
@@ -59,7 +59,7 @@ object FirMemberPropertiesChecker : FirClassChecker() {
|
||||
private fun checkProperty(
|
||||
containingDeclaration: FirClass,
|
||||
property: FirProperty,
|
||||
isInitialized: Boolean,
|
||||
isDefinitelyAssignedInConstructor: Boolean,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter,
|
||||
reachable: Boolean
|
||||
@@ -74,7 +74,7 @@ object FirMemberPropertiesChecker : FirClassChecker() {
|
||||
containingDeclaration,
|
||||
property,
|
||||
modifierList,
|
||||
isInitialized,
|
||||
isDefinitelyAssignedInConstructor,
|
||||
reporter,
|
||||
context,
|
||||
reachable
|
||||
|
||||
+25
-10
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
@@ -42,7 +44,7 @@ object FirTopLevelPropertiesChecker : FirPropertyChecker() {
|
||||
containingClass = null,
|
||||
declaration,
|
||||
modifierList,
|
||||
isInitialized = declaration.initializer != null,
|
||||
isDefinitelyAssignedInConstructor = false, // Only member properties can be assigned in constructors
|
||||
reporter,
|
||||
context
|
||||
)
|
||||
@@ -72,7 +74,7 @@ internal fun checkPropertyInitializer(
|
||||
containingClass: FirClass?,
|
||||
property: FirProperty,
|
||||
modifierList: FirModifierList?,
|
||||
isInitialized: Boolean,
|
||||
isDefinitelyAssignedInConstructor: Boolean,
|
||||
reporter: DiagnosticReporter,
|
||||
context: CheckerContext,
|
||||
reachable: Boolean = true
|
||||
@@ -94,7 +96,7 @@ internal fun checkPropertyInitializer(
|
||||
}
|
||||
|
||||
val backingFieldRequired = property.hasBackingField
|
||||
if (inInterface && backingFieldRequired && property.hasAccessorImplementation) {
|
||||
if (inInterface && backingFieldRequired && property.hasAnyAccessorImplementation) {
|
||||
property.source?.let {
|
||||
reporter.reportOn(it, FirErrors.BACKING_FIELD_IN_INTERFACE, context)
|
||||
}
|
||||
@@ -136,19 +138,22 @@ internal fun checkPropertyInitializer(
|
||||
else -> {
|
||||
val propertySource = property.source ?: return
|
||||
val isExternal = property.isEffectivelyExternal(containingClass, context)
|
||||
val isCorrectlyInitialized =
|
||||
property.initializer != null || isDefinitelyAssignedInConstructor && !property.hasSetterAccessorImplementation &&
|
||||
property.getEffectiveModality(containingClass, context.languageVersionSettings) != Modality.OPEN
|
||||
if (
|
||||
backingFieldRequired &&
|
||||
!inInterface &&
|
||||
!property.isLateInit &&
|
||||
!isExpect &&
|
||||
!isInitialized &&
|
||||
!isCorrectlyInitialized &&
|
||||
!isExternal &&
|
||||
!property.hasExplicitBackingField
|
||||
) {
|
||||
if (property.receiverParameter != null && !property.hasAccessorImplementation) {
|
||||
if (property.receiverParameter != null && !property.hasAnyAccessorImplementation) {
|
||||
reporter.reportOn(propertySource, FirErrors.EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT, context)
|
||||
} else if (reachable) { // TODO: can be suppressed not to report diagnostics about no body
|
||||
if (containingClass == null || property.hasAccessorImplementation) {
|
||||
if (containingClass == null || property.hasAnyAccessorImplementation) {
|
||||
reporter.reportOn(propertySource, FirErrors.MUST_BE_INITIALIZED, context)
|
||||
} else {
|
||||
reporter.reportOn(propertySource, FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT, context)
|
||||
@@ -160,7 +165,7 @@ internal fun checkPropertyInitializer(
|
||||
reporter.reportOn(propertySource, FirErrors.EXPECTED_LATEINIT_PROPERTY, context)
|
||||
}
|
||||
// TODO: like [BindingContext.MUST_BE_LATEINIT], we should consider variable with uninitialized error.
|
||||
if (backingFieldRequired && !inInterface && isInitialized) {
|
||||
if (backingFieldRequired && !inInterface && isCorrectlyInitialized) {
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.EnableDfaWarningsInK2)) {
|
||||
reporter.reportOn(propertySource, FirErrors.UNNECESSARY_LATEINIT, context)
|
||||
}
|
||||
@@ -170,6 +175,16 @@ internal fun checkPropertyInitializer(
|
||||
}
|
||||
}
|
||||
|
||||
private val FirProperty.hasAccessorImplementation: Boolean
|
||||
get() = (getter !is FirDefaultPropertyAccessor && getter?.hasBody == true) ||
|
||||
(setter !is FirDefaultPropertyAccessor && setter?.hasBody == true)
|
||||
private val FirPropertyAccessor?.hasImplementation: Boolean
|
||||
get() = (this !is FirDefaultPropertyAccessor && this?.hasBody == true)
|
||||
private val FirProperty.hasSetterAccessorImplementation: Boolean
|
||||
get() = setter.hasImplementation
|
||||
private val FirProperty.hasAnyAccessorImplementation: Boolean
|
||||
get() = getter.hasImplementation || setter.hasImplementation
|
||||
|
||||
private fun FirProperty.getEffectiveModality(containingClass: FirClass?, languageVersionSettings: LanguageVersionSettings): Modality? =
|
||||
when (languageVersionSettings.supportsFeature(LanguageFeature.TakeIntoAccountEffectivelyFinalInMustBeInitializedCheck) &&
|
||||
status.modality == Modality.OPEN && containingClass?.status?.modality == Modality.FINAL) {
|
||||
true -> Modality.FINAL
|
||||
false -> status.modality
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
class My(val v: Int) {
|
||||
// Ok: setter is just private
|
||||
var x: Int
|
||||
private set
|
||||
|
||||
var y: Int
|
||||
set(arg) { field = arg }
|
||||
|
||||
<!MUST_BE_INITIALIZED!>var z: Int<!>
|
||||
set(arg) { field = arg }
|
||||
|
||||
// Ok: initializer available
|
||||
var w: Int = v
|
||||
set(arg) { field = arg }
|
||||
|
||||
// Ok: no backing field
|
||||
var u: Int
|
||||
get() = w
|
||||
set(arg) { w = 2 * arg }
|
||||
|
||||
constructor(): this(0) {
|
||||
z = v
|
||||
}
|
||||
|
||||
init {
|
||||
x = 1
|
||||
y = 2
|
||||
u = 3
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class My(val v: Int) {
|
||||
// Ok: setter is just private
|
||||
var x: Int
|
||||
|
||||
@@ -2,7 +2,7 @@ abstract class My(val v: Int) {
|
||||
// Ok: variable is just abstract
|
||||
abstract var x: Int
|
||||
|
||||
open var y: Int
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open var y: Int<!>
|
||||
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open var z: Int<!>
|
||||
|
||||
|
||||
Vendored
-12
@@ -1,12 +0,0 @@
|
||||
// !LANGUAGE:-TakeIntoAccountEffectivelyFinalInMustBeInitializedCheck
|
||||
open class Base {
|
||||
open var x: String = ""
|
||||
}
|
||||
|
||||
class Foo : Base() {
|
||||
override var x: String
|
||||
|
||||
init {
|
||||
x = ""
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE:-TakeIntoAccountEffectivelyFinalInMustBeInitializedCheck
|
||||
open class Base {
|
||||
open var x: String = ""
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// !DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS
|
||||
// a = final + not initialized in place + deferred init
|
||||
// e = final + not initialized in place
|
||||
// c = final + initialized in place
|
||||
|
||||
// b = open + not initialized in place + deferred init
|
||||
// f = open + not initialized in place
|
||||
// d = open + initialized in place
|
||||
open class Foo {
|
||||
// no getter
|
||||
val a0: Int
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val e0: Int<!>
|
||||
val c0: Int = 1
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open val b0: Int<!>
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open val f0: Int<!>
|
||||
open val d0: Int = 1
|
||||
|
||||
// getter with field
|
||||
val a1: Int; get() = field
|
||||
<!MUST_BE_INITIALIZED!>val e1: Int<!>; get() = field
|
||||
val c1: Int = 1; get() = field
|
||||
<!MUST_BE_INITIALIZED!>open val b1: Int<!>; get() = field
|
||||
<!MUST_BE_INITIALIZED!>open val f1: Int<!>; get() = field
|
||||
open val d1: Int = 1; get() = field
|
||||
|
||||
// getter with empty body
|
||||
val a2: Int; get
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val e2: Int<!>; get
|
||||
val c2: Int = 1; get
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open val b2: Int<!>; get
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open val f2: Int<!>; get
|
||||
open val d2: Int = 1; get
|
||||
|
||||
// getter no field
|
||||
val a3: Int; get() = 1
|
||||
val e3: Int; get() = 1
|
||||
val c3: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>1<!>; get() = 1
|
||||
open val b3: Int; get() = 1
|
||||
open val f3: Int; get() = 1
|
||||
open val d3: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>1<!>; get() = 1
|
||||
|
||||
init {
|
||||
a0 = 1
|
||||
a1 = 1
|
||||
a2 = 1
|
||||
<!VAL_REASSIGNMENT!>a3<!> = 1
|
||||
|
||||
b0 = 1
|
||||
b1 = 1
|
||||
b2 = 1
|
||||
<!VAL_REASSIGNMENT!>b3<!> = 1
|
||||
}
|
||||
}
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS
|
||||
// a = final + not initialized in place + deferred init
|
||||
// e = final + not initialized in place
|
||||
|
||||
-128
@@ -1,128 +0,0 @@
|
||||
// !DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS
|
||||
// a = final + not initialized in place + deferred init
|
||||
// e = final + not initialized in place
|
||||
// c = final + initialized in place
|
||||
|
||||
// b = open + not initialized in place + deferred init
|
||||
// f = open + not initialized in place
|
||||
// d = open + initialized in place
|
||||
class Foo : I {
|
||||
// no setter; setter with field; setter with empty body; setter no field;
|
||||
// no getter
|
||||
var a00: Int; var a01: Int; set(v) { field = v }; var a02: Int; set; var a03: Int; set(v) {};
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>var e00: Int<!>; <!MUST_BE_INITIALIZED!>var e01: Int<!>; set(v) { field = v }; <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>var e02: Int<!>; set; <!MUST_BE_INITIALIZED!>var e03: Int<!>; set(v) {};
|
||||
var c00: Int = 1; var c01: Int = 1; set(v) { field = v }; var c02: Int = 1; set; var c03: Int = 1; set(v) {};
|
||||
override var b00: Int; override var b01: Int; set(v) { field = v }; override var b02: Int; set; override var b03: Int; set(v) {};
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>override var f00: Int<!>; <!MUST_BE_INITIALIZED!>override var f01: Int<!>; set(v) { field = v }; <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>override var f02: Int<!>; set; <!MUST_BE_INITIALIZED!>override var f03: Int<!>; set(v) {};
|
||||
override var d00: Int = 1; override var d01: Int = 1; set(v) { field = v }; override var d02: Int = 1; set; override var d03: Int = 1; set(v) {};
|
||||
// getter with field
|
||||
var a10: Int; get() = field; var a11: Int; set(v) { field = v } get() = field; var a12: Int; set get() = field; var a13: Int; set(v) {} get() = field;
|
||||
<!MUST_BE_INITIALIZED!>var e10: Int<!>; get() = field; <!MUST_BE_INITIALIZED!>var e11: Int<!>; set(v) { field = v } get() = field; <!MUST_BE_INITIALIZED!>var e12: Int<!>; set get() = field; <!MUST_BE_INITIALIZED!>var e13: Int<!>; set(v) {} get() = field;
|
||||
var c10: Int = 1; get() = field; var c11: Int = 1; set(v) { field = v } get() = field; var c12: Int = 1; set get() = field; var c13: Int = 1; set(v) {} get() = field;
|
||||
override var b10: Int; get() = field; override var b11: Int; set(v) { field = v } get() = field; override var b12: Int; set get() = field; override var b13: Int; set(v) {} get() = field;
|
||||
<!MUST_BE_INITIALIZED!>override var f10: Int<!>; get() = field; <!MUST_BE_INITIALIZED!>override var f11: Int<!>; set(v) { field = v } get() = field; <!MUST_BE_INITIALIZED!>override var f12: Int<!>; set get() = field; <!MUST_BE_INITIALIZED!>override var f13: Int<!>; set(v) {} get() = field;
|
||||
override var d10: Int = 1; get() = field; override var d11: Int = 1; set(v) { field = v } get() = field; override var d12: Int = 1; set get() = field; override var d13: Int = 1; set(v) {} get() = field;
|
||||
// getter with empty body
|
||||
var a20: Int; get; var a21: Int; set(v) { field = v } get; var a22: Int; set get; var a23: Int; set(v) {} get;
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>var e20: Int<!>; get; <!MUST_BE_INITIALIZED!>var e21: Int<!>; set(v) { field = v } get; <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>var e22: Int<!>; set get; <!MUST_BE_INITIALIZED!>var e23: Int<!>; set(v) {} get;
|
||||
var c20: Int = 1; get; var c21: Int = 1; set(v) { field = v } get; var c22: Int = 1; set get; var c23: Int = 1; set(v) {} get;
|
||||
override var b20: Int; get; override var b21: Int; set(v) { field = v } get; override var b22: Int; set get; override var b23: Int; set(v) {} get;
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>override var f20: Int<!>; get; <!MUST_BE_INITIALIZED!>override var f21: Int<!>; set(v) { field = v } get; <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>override var f22: Int<!>; set get; <!MUST_BE_INITIALIZED!>override var f23: Int<!>; set(v) {} get;
|
||||
override var d20: Int = 1; get; override var d21: Int = 1; set(v) { field = v } get; override var d22: Int = 1; set get; override var d23: Int = 1; set(v) {} get;
|
||||
// getter no field
|
||||
var a30: Int; get() = 1; var a31: Int; set(v) { field = v } get() = 1; var a32: Int; set get() = 1; var a33: Int; set(v) {} get() = 1;
|
||||
<!MUST_BE_INITIALIZED!>var e30: Int<!>; get() = 1; <!MUST_BE_INITIALIZED!>var e31: Int<!>; set(v) { field = v } get() = 1; <!MUST_BE_INITIALIZED!>var e32: Int<!>; set get() = 1; var e33: Int; set(v) {} get() = 1;
|
||||
var c30: Int = 1; get() = 1; var c31: Int = 1; set(v) { field = v } get() = 1; var c32: Int = 1; set get() = 1; var c33: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>1<!>; set(v) {} get() = 1;
|
||||
override var b30: Int; get() = 1; override var b31: Int; set(v) { field = v } get() = 1; override var b32: Int; set get() = 1; override var b33: Int; set(v) {} get() = 1;
|
||||
<!MUST_BE_INITIALIZED!>override var f30: Int<!>; get() = 1; <!MUST_BE_INITIALIZED!>override var f31: Int<!>; set(v) { field = v } get() = 1; <!MUST_BE_INITIALIZED!>override var f32: Int<!>; set get() = 1; override var f33: Int; set(v) {} get() = 1;
|
||||
override var d30: Int = 1; get() = 1; override var d31: Int = 1; set(v) { field = v } get() = 1; override var d32: Int = 1; set get() = 1; override var d33: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>1<!>; set(v) {} get() = 1;
|
||||
|
||||
init {
|
||||
a00 = 1
|
||||
a01 = 1
|
||||
a02 = 1
|
||||
a03 = 1
|
||||
a10 = 1
|
||||
a11 = 1
|
||||
a12 = 1
|
||||
a13 = 1
|
||||
a20 = 1
|
||||
a21 = 1
|
||||
a22 = 1
|
||||
a23 = 1
|
||||
a30 = 1
|
||||
a31 = 1
|
||||
a32 = 1
|
||||
a33 = 1
|
||||
|
||||
b00 = 1
|
||||
b01 = 1
|
||||
b02 = 1
|
||||
b03 = 1
|
||||
b10 = 1
|
||||
b11 = 1
|
||||
b12 = 1
|
||||
b13 = 1
|
||||
b20 = 1
|
||||
b21 = 1
|
||||
b22 = 1
|
||||
b23 = 1
|
||||
b30 = 1
|
||||
b31 = 1
|
||||
b32 = 1
|
||||
b33 = 1
|
||||
}
|
||||
}
|
||||
|
||||
interface I {
|
||||
val b00: Int
|
||||
val b01: Int
|
||||
val b02: Int
|
||||
val b03: Int
|
||||
val b10: Int
|
||||
val b11: Int
|
||||
val b12: Int
|
||||
val b13: Int
|
||||
val b20: Int
|
||||
val b21: Int
|
||||
val b22: Int
|
||||
val b23: Int
|
||||
val b30: Int
|
||||
val b31: Int
|
||||
val b32: Int
|
||||
val b33: Int
|
||||
|
||||
val f00: Int
|
||||
val f01: Int
|
||||
val f02: Int
|
||||
val f03: Int
|
||||
val f10: Int
|
||||
val f11: Int
|
||||
val f12: Int
|
||||
val f13: Int
|
||||
val f20: Int
|
||||
val f21: Int
|
||||
val f22: Int
|
||||
val f23: Int
|
||||
val f30: Int
|
||||
val f31: Int
|
||||
val f32: Int
|
||||
val f33: Int
|
||||
|
||||
val d00: Int
|
||||
val d01: Int
|
||||
val d02: Int
|
||||
val d03: Int
|
||||
val d10: Int
|
||||
val d11: Int
|
||||
val d12: Int
|
||||
val d13: Int
|
||||
val d20: Int
|
||||
val d21: Int
|
||||
val d22: Int
|
||||
val d23: Int
|
||||
val d30: Int
|
||||
val d31: Int
|
||||
val d32: Int
|
||||
val d33: Int
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS
|
||||
// a = final + not initialized in place + deferred init
|
||||
// e = final + not initialized in place
|
||||
|
||||
-75
@@ -1,75 +0,0 @@
|
||||
// !DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS
|
||||
// a = final + not initialized in place + deferred init
|
||||
// e = final + not initialized in place
|
||||
// c = final + initialized in place
|
||||
|
||||
// b = open + not initialized in place + deferred init
|
||||
// f = open + not initialized in place
|
||||
// d = open + initialized in place
|
||||
open class Foo {
|
||||
// no setter; setter with field; setter with empty body; setter no field;
|
||||
// no getter
|
||||
var a00: Int; var a01: Int; set(v) { field = v }; var a02: Int; set; var a03: Int; set(v) {};
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>var e00: Int<!>; <!MUST_BE_INITIALIZED!>var e01: Int<!>; set(v) { field = v }; <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>var e02: Int<!>; set; <!MUST_BE_INITIALIZED!>var e03: Int<!>; set(v) {};
|
||||
var c00: Int = 1; var c01: Int = 1; set(v) { field = v }; var c02: Int = 1; set; var c03: Int = 1; set(v) {};
|
||||
open var b00: Int; open var b01: Int; set(v) { field = v }; open var b02: Int; set; open var b03: Int; set(v) {};
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open var f00: Int<!>; <!MUST_BE_INITIALIZED!>open var f01: Int<!>; set(v) { field = v }; <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open var f02: Int<!>; set; <!MUST_BE_INITIALIZED!>open var f03: Int<!>; set(v) {};
|
||||
open var d00: Int = 1; open var d01: Int = 1; set(v) { field = v }; open var d02: Int = 1; set; open var d03: Int = 1; set(v) {};
|
||||
// getter with field
|
||||
var a10: Int; get() = field; var a11: Int; set(v) { field = v } get() = field; var a12: Int; set get() = field; var a13: Int; set(v) {} get() = field;
|
||||
<!MUST_BE_INITIALIZED!>var e10: Int<!>; get() = field; <!MUST_BE_INITIALIZED!>var e11: Int<!>; set(v) { field = v } get() = field; <!MUST_BE_INITIALIZED!>var e12: Int<!>; set get() = field; <!MUST_BE_INITIALIZED!>var e13: Int<!>; set(v) {} get() = field;
|
||||
var c10: Int = 1; get() = field; var c11: Int = 1; set(v) { field = v } get() = field; var c12: Int = 1; set get() = field; var c13: Int = 1; set(v) {} get() = field;
|
||||
open var b10: Int; get() = field; open var b11: Int; set(v) { field = v } get() = field; open var b12: Int; set get() = field; open var b13: Int; set(v) {} get() = field;
|
||||
<!MUST_BE_INITIALIZED!>open var f10: Int<!>; get() = field; <!MUST_BE_INITIALIZED!>open var f11: Int<!>; set(v) { field = v } get() = field; <!MUST_BE_INITIALIZED!>open var f12: Int<!>; set get() = field; <!MUST_BE_INITIALIZED!>open var f13: Int<!>; set(v) {} get() = field;
|
||||
open var d10: Int = 1; get() = field; open var d11: Int = 1; set(v) { field = v } get() = field; open var d12: Int = 1; set get() = field; open var d13: Int = 1; set(v) {} get() = field;
|
||||
// getter with empty body
|
||||
var a20: Int; get; var a21: Int; set(v) { field = v } get; var a22: Int; set get; var a23: Int; set(v) {} get;
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>var e20: Int<!>; get; <!MUST_BE_INITIALIZED!>var e21: Int<!>; set(v) { field = v } get; <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>var e22: Int<!>; set get; <!MUST_BE_INITIALIZED!>var e23: Int<!>; set(v) {} get;
|
||||
var c20: Int = 1; get; var c21: Int = 1; set(v) { field = v } get; var c22: Int = 1; set get; var c23: Int = 1; set(v) {} get;
|
||||
open var b20: Int; get; open var b21: Int; set(v) { field = v } get; open var b22: Int; set get; open var b23: Int; set(v) {} get;
|
||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open var f20: Int<!>; get; <!MUST_BE_INITIALIZED!>open var f21: Int<!>; set(v) { field = v } get; <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open var f22: Int<!>; set get; <!MUST_BE_INITIALIZED!>open var f23: Int<!>; set(v) {} get;
|
||||
open var d20: Int = 1; get; open var d21: Int = 1; set(v) { field = v } get; open var d22: Int = 1; set get; open var d23: Int = 1; set(v) {} get;
|
||||
// getter no field
|
||||
var a30: Int; get() = 1; var a31: Int; set(v) { field = v } get() = 1; var a32: Int; set get() = 1; var a33: Int; set(v) {} get() = 1;
|
||||
<!MUST_BE_INITIALIZED!>var e30: Int<!>; get() = 1; <!MUST_BE_INITIALIZED!>var e31: Int<!>; set(v) { field = v } get() = 1; <!MUST_BE_INITIALIZED!>var e32: Int<!>; set get() = 1; var e33: Int; set(v) {} get() = 1;
|
||||
var c30: Int = 1; get() = 1; var c31: Int = 1; set(v) { field = v } get() = 1; var c32: Int = 1; set get() = 1; var c33: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>1<!>; set(v) {} get() = 1;
|
||||
open var b30: Int; get() = 1; open var b31: Int; set(v) { field = v } get() = 1; open var b32: Int; set get() = 1; open var b33: Int; set(v) {} get() = 1;
|
||||
<!MUST_BE_INITIALIZED!>open var f30: Int<!>; get() = 1; <!MUST_BE_INITIALIZED!>open var f31: Int<!>; set(v) { field = v } get() = 1; <!MUST_BE_INITIALIZED!>open var f32: Int<!>; set get() = 1; open var f33: Int; set(v) {} get() = 1;
|
||||
open var d30: Int = 1; get() = 1; open var d31: Int = 1; set(v) { field = v } get() = 1; open var d32: Int = 1; set get() = 1; open var d33: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>1<!>; set(v) {} get() = 1;
|
||||
|
||||
init {
|
||||
a00 = 1
|
||||
a01 = 1
|
||||
a02 = 1
|
||||
a03 = 1
|
||||
a10 = 1
|
||||
a11 = 1
|
||||
a12 = 1
|
||||
a13 = 1
|
||||
a20 = 1
|
||||
a21 = 1
|
||||
a22 = 1
|
||||
a23 = 1
|
||||
a30 = 1
|
||||
a31 = 1
|
||||
a32 = 1
|
||||
a33 = 1
|
||||
|
||||
b00 = 1
|
||||
b01 = 1
|
||||
b02 = 1
|
||||
b03 = 1
|
||||
b10 = 1
|
||||
b11 = 1
|
||||
b12 = 1
|
||||
b13 = 1
|
||||
b20 = 1
|
||||
b21 = 1
|
||||
b22 = 1
|
||||
b23 = 1
|
||||
b30 = 1
|
||||
b31 = 1
|
||||
b32 = 1
|
||||
b33 = 1
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS
|
||||
// a = final + not initialized in place + deferred init
|
||||
// e = final + not initialized in place
|
||||
|
||||
@@ -155,83 +155,3 @@ FILE fqName:<root> fileName:/initVar.kt
|
||||
overridden:
|
||||
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
CLASS CLASS name:TestInitVarWithCustomSetterWithExplicitCtor modality:FINAL visibility:public superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.TestInitVarWithCustomSetterWithExplicitCtor
|
||||
PROPERTY name:x visibility:public modality:FINAL [var]
|
||||
FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-x> visibility:public modality:FINAL <> ($this:<root>.TestInitVarWithCustomSetterWithExplicitCtor) returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [var]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.TestInitVarWithCustomSetterWithExplicitCtor
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-x> (): kotlin.Int declared in <root>.TestInitVarWithCustomSetterWithExplicitCtor'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private' type=kotlin.Int origin=null
|
||||
receiver: GET_VAR '<this>: <root>.TestInitVarWithCustomSetterWithExplicitCtor declared in <root>.TestInitVarWithCustomSetterWithExplicitCtor.<get-x>' type=<root>.TestInitVarWithCustomSetterWithExplicitCtor origin=null
|
||||
FUN name:<set-x> visibility:public modality:FINAL <> ($this:<root>.TestInitVarWithCustomSetterWithExplicitCtor, value:kotlin.Int) returnType:kotlin.Unit
|
||||
correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [var]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.TestInitVarWithCustomSetterWithExplicitCtor
|
||||
VALUE_PARAMETER name:value index:0 type:kotlin.Int
|
||||
BLOCK_BODY
|
||||
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private' type=kotlin.Unit origin=EQ
|
||||
receiver: GET_VAR '<this>: <root>.TestInitVarWithCustomSetterWithExplicitCtor declared in <root>.TestInitVarWithCustomSetterWithExplicitCtor.<set-x>' type=<root>.TestInitVarWithCustomSetterWithExplicitCtor origin=null
|
||||
value: GET_VAR 'value: kotlin.Int declared in <root>.TestInitVarWithCustomSetterWithExplicitCtor.<set-x>' type=kotlin.Int origin=null
|
||||
ANONYMOUS_INITIALIZER isStatic=false
|
||||
BLOCK_BODY
|
||||
CALL 'public final fun <set-x> (value: kotlin.Int): kotlin.Unit declared in <root>.TestInitVarWithCustomSetterWithExplicitCtor' type=kotlin.Unit origin=EQ
|
||||
$this: GET_VAR '<this>: <root>.TestInitVarWithCustomSetterWithExplicitCtor declared in <root>.TestInitVarWithCustomSetterWithExplicitCtor' type=<root>.TestInitVarWithCustomSetterWithExplicitCtor origin=null
|
||||
value: CONST Int type=kotlin.Int value=0
|
||||
CONSTRUCTOR visibility:public <> () returnType:<root>.TestInitVarWithCustomSetterWithExplicitCtor
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:TestInitVarWithCustomSetterWithExplicitCtor modality:FINAL visibility:public superTypes:[kotlin.Any]'
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
overridden:
|
||||
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
|
||||
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
|
||||
overridden:
|
||||
public open fun hashCode (): kotlin.Int declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
|
||||
overridden:
|
||||
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
CLASS CLASS name:TestInitVarWithCustomSetterInCtor modality:FINAL visibility:public superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.TestInitVarWithCustomSetterInCtor
|
||||
PROPERTY name:x visibility:public modality:FINAL [var]
|
||||
FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-x> visibility:public modality:FINAL <> ($this:<root>.TestInitVarWithCustomSetterInCtor) returnType:kotlin.Int
|
||||
correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [var]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.TestInitVarWithCustomSetterInCtor
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun <get-x> (): kotlin.Int declared in <root>.TestInitVarWithCustomSetterInCtor'
|
||||
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private' type=kotlin.Int origin=null
|
||||
receiver: GET_VAR '<this>: <root>.TestInitVarWithCustomSetterInCtor declared in <root>.TestInitVarWithCustomSetterInCtor.<get-x>' type=<root>.TestInitVarWithCustomSetterInCtor origin=null
|
||||
FUN name:<set-x> visibility:public modality:FINAL <> ($this:<root>.TestInitVarWithCustomSetterInCtor, value:kotlin.Int) returnType:kotlin.Unit
|
||||
correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [var]
|
||||
$this: VALUE_PARAMETER name:<this> type:<root>.TestInitVarWithCustomSetterInCtor
|
||||
VALUE_PARAMETER name:value index:0 type:kotlin.Int
|
||||
BLOCK_BODY
|
||||
SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:private' type=kotlin.Unit origin=EQ
|
||||
receiver: GET_VAR '<this>: <root>.TestInitVarWithCustomSetterInCtor declared in <root>.TestInitVarWithCustomSetterInCtor.<set-x>' type=<root>.TestInitVarWithCustomSetterInCtor origin=null
|
||||
value: GET_VAR 'value: kotlin.Int declared in <root>.TestInitVarWithCustomSetterInCtor.<set-x>' type=kotlin.Int origin=null
|
||||
CONSTRUCTOR visibility:public <> () returnType:<root>.TestInitVarWithCustomSetterInCtor
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:TestInitVarWithCustomSetterInCtor modality:FINAL visibility:public superTypes:[kotlin.Any]'
|
||||
CALL 'public final fun <set-x> (value: kotlin.Int): kotlin.Unit declared in <root>.TestInitVarWithCustomSetterInCtor' type=kotlin.Unit origin=EQ
|
||||
$this: GET_VAR '<this>: <root>.TestInitVarWithCustomSetterInCtor declared in <root>.TestInitVarWithCustomSetterInCtor' type=<root>.TestInitVarWithCustomSetterInCtor origin=null
|
||||
value: CONST Int type=kotlin.Int value=42
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
|
||||
overridden:
|
||||
public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
|
||||
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
|
||||
overridden:
|
||||
public open fun hashCode (): kotlin.Int declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
|
||||
overridden:
|
||||
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
|
||||
-21
@@ -16,24 +16,3 @@ class TestInitVarWithCustomSetter {
|
||||
var x = 0
|
||||
set(value) { field = value }
|
||||
}
|
||||
|
||||
class TestInitVarWithCustomSetterWithExplicitCtor {
|
||||
var x: Int
|
||||
set(value) { field = value }
|
||||
|
||||
init {
|
||||
x = 0
|
||||
}
|
||||
|
||||
constructor()
|
||||
}
|
||||
|
||||
class TestInitVarWithCustomSetterInCtor {
|
||||
var x: Int set(value) {
|
||||
field = value
|
||||
}
|
||||
|
||||
constructor() {
|
||||
x = 42
|
||||
}
|
||||
}
|
||||
@@ -59,37 +59,3 @@ class TestInitVarWithCustomSetter {
|
||||
|
||||
}
|
||||
|
||||
class TestInitVarWithCustomSetterWithExplicitCtor {
|
||||
var x: Int
|
||||
get
|
||||
set(value: Int) {
|
||||
<this>.#x = value
|
||||
}
|
||||
|
||||
init {
|
||||
<this>.<set-x>(value = 0)
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super/*Any*/()
|
||||
/* <init>() */
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TestInitVarWithCustomSetterInCtor {
|
||||
var x: Int
|
||||
get
|
||||
set(value: Int) {
|
||||
<this>.#x = value
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super/*Any*/()
|
||||
/* <init>() */
|
||||
|
||||
<this>.<set-x>(value = 42)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -106,57 +106,3 @@ class TestInitVarWithCustomSetter {
|
||||
|
||||
}
|
||||
|
||||
// CHECK:
|
||||
// Mangled name: TestInitVarWithCustomSetterInCtor
|
||||
// Public signature: /TestInitVarWithCustomSetterInCtor|null[0]
|
||||
class TestInitVarWithCustomSetterInCtor {
|
||||
// CHECK:
|
||||
// Mangled name: TestInitVarWithCustomSetterInCtor{}x
|
||||
// Public signature: /TestInitVarWithCustomSetterInCtor.x|-8060530855978347579[0]
|
||||
var x: Int
|
||||
// CHECK JVM_IR:
|
||||
// Mangled name: TestInitVarWithCustomSetterInCtor#<get-x>(){}kotlin.Int
|
||||
// Public signature: /TestInitVarWithCustomSetterInCtor.x.<get-x>|4966956098150895696[0]
|
||||
// CHECK JS_IR NATIVE:
|
||||
// Mangled name: TestInitVarWithCustomSetterInCtor#<get-x>(){}
|
||||
// Public signature: /TestInitVarWithCustomSetterInCtor.x.<get-x>|1482705010654679335[0]
|
||||
get
|
||||
// CHECK:
|
||||
// Mangled name: TestInitVarWithCustomSetterInCtor#<set-x>(kotlin.Int){}
|
||||
// Public signature: /TestInitVarWithCustomSetterInCtor.x.<set-x>|-740209739415615559[0]
|
||||
set(value: Int): Unit
|
||||
|
||||
// CHECK:
|
||||
// Mangled name: TestInitVarWithCustomSetterInCtor#<init>(){}
|
||||
// Public signature: /TestInitVarWithCustomSetterInCtor.<init>|-5645683436151566731[0]
|
||||
constructor()
|
||||
|
||||
}
|
||||
|
||||
// CHECK:
|
||||
// Mangled name: TestInitVarWithCustomSetterWithExplicitCtor
|
||||
// Public signature: /TestInitVarWithCustomSetterWithExplicitCtor|null[0]
|
||||
class TestInitVarWithCustomSetterWithExplicitCtor {
|
||||
// CHECK:
|
||||
// Mangled name: TestInitVarWithCustomSetterWithExplicitCtor{}x
|
||||
// Public signature: /TestInitVarWithCustomSetterWithExplicitCtor.x|-8060530855978347579[0]
|
||||
var x: Int
|
||||
// CHECK JVM_IR:
|
||||
// Mangled name: TestInitVarWithCustomSetterWithExplicitCtor#<get-x>(){}kotlin.Int
|
||||
// Public signature: /TestInitVarWithCustomSetterWithExplicitCtor.x.<get-x>|4966956098150895696[0]
|
||||
// CHECK JS_IR NATIVE:
|
||||
// Mangled name: TestInitVarWithCustomSetterWithExplicitCtor#<get-x>(){}
|
||||
// Public signature: /TestInitVarWithCustomSetterWithExplicitCtor.x.<get-x>|1482705010654679335[0]
|
||||
get
|
||||
// CHECK:
|
||||
// Mangled name: TestInitVarWithCustomSetterWithExplicitCtor#<set-x>(kotlin.Int){}
|
||||
// Public signature: /TestInitVarWithCustomSetterWithExplicitCtor.x.<set-x>|-740209739415615559[0]
|
||||
set(value: Int): Unit
|
||||
|
||||
// CHECK:
|
||||
// Mangled name: TestInitVarWithCustomSetterWithExplicitCtor#<init>(){}
|
||||
// Public signature: /TestInitVarWithCustomSetterWithExplicitCtor.<init>|-5645683436151566731[0]
|
||||
constructor()
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user