[FE] Replace some MUST_BE_INITIALIZED messages with MUST_BE_INITIALIZED_OR_BE_FINAL

From user point of view it's an improvement in compilation message.

From technical point of view it's an introduction of new compilation
diagnostic.

Review: https://jetbrains.team/p/kt/reviews/9967

I'm going to deprecate `open val` case in the next few commits KT-57553.
But it is always possible to suggest using `final` for `open val` case.
This commit is contained in:
Nikita Bobko
2023-05-15 12:28:56 +02:00
parent d9d4dee582
commit 38319c55a8
18 changed files with 124 additions and 38 deletions
@@ -2851,12 +2851,24 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token,
)
}
add(FirErrors.MUST_BE_INITIALIZED_OR_BE_FINAL) { firDiagnostic ->
MustBeInitializedOrBeFinalImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT) { firDiagnostic ->
MustBeInitializedOrBeAbstractImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT) { firDiagnostic ->
MustBeInitializedOrFinalOrAbstractImpl(
firDiagnostic as KtPsiDiagnostic,
token,
)
}
add(FirErrors.EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT) { firDiagnostic ->
ExtensionPropertyMustHaveAccessorsOrBeAbstractImpl(
firDiagnostic as KtPsiDiagnostic,
@@ -2019,10 +2019,18 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = MustBeInitialized::class
}
abstract class MustBeInitializedOrBeFinal : KtFirDiagnostic<KtProperty>() {
override val diagnosticClass get() = MustBeInitializedOrBeFinal::class
}
abstract class MustBeInitializedOrBeAbstract : KtFirDiagnostic<KtProperty>() {
override val diagnosticClass get() = MustBeInitializedOrBeAbstract::class
}
abstract class MustBeInitializedOrFinalOrAbstract : KtFirDiagnostic<KtProperty>() {
override val diagnosticClass get() = MustBeInitializedOrFinalOrAbstract::class
}
abstract class ExtensionPropertyMustHaveAccessorsOrBeAbstract : KtFirDiagnostic<KtProperty>() {
override val diagnosticClass get() = ExtensionPropertyMustHaveAccessorsOrBeAbstract::class
}
@@ -2425,11 +2425,21 @@ internal class MustBeInitializedImpl(
override val token: KtLifetimeToken,
) : KtFirDiagnostic.MustBeInitialized(), KtAbstractFirDiagnostic<KtProperty>
internal class MustBeInitializedOrBeFinalImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
) : KtFirDiagnostic.MustBeInitializedOrBeFinal(), KtAbstractFirDiagnostic<KtProperty>
internal class MustBeInitializedOrBeAbstractImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
) : KtFirDiagnostic.MustBeInitializedOrBeAbstract(), KtAbstractFirDiagnostic<KtProperty>
internal class MustBeInitializedOrFinalOrAbstractImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
) : KtFirDiagnostic.MustBeInitializedOrFinalOrAbstract(), KtAbstractFirDiagnostic<KtProperty>
internal class ExtensionPropertyMustHaveAccessorsOrBeAbstractImpl(
override val firDiagnostic: KtPsiDiagnostic,
override val token: KtLifetimeToken,
@@ -1009,7 +1009,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val PROPERTY_WITH_NO_TYPE_NO_INITIALIZER by error<KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
val MUST_BE_INITIALIZED by error<KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
val MUST_BE_INITIALIZED_OR_BE_FINAL by error<KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
val MUST_BE_INITIALIZED_OR_BE_ABSTRACT by error<KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
val MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT by error<KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
val EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT by error<KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
val UNNECESSARY_LATEINIT by warning<KtProperty>(PositioningStrategy.LATEINIT_MODIFIER)
@@ -533,7 +533,9 @@ object FirErrors {
val PROPERTY_INITIALIZER_IN_INTERFACE by error0<KtExpression>()
val PROPERTY_WITH_NO_TYPE_NO_INITIALIZER by error0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val MUST_BE_INITIALIZED by error0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val MUST_BE_INITIALIZED_OR_BE_FINAL by error0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val MUST_BE_INITIALIZED_OR_BE_ABSTRACT by error0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT by error0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT by error0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val UNNECESSARY_LATEINIT by warning0<KtProperty>(SourceElementPositioningStrategies.LATEINIT_MODIFIER)
val BACKING_FIELD_IN_INTERFACE by error0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
@@ -153,11 +153,7 @@ internal fun checkPropertyInitializer(
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.hasAnyAccessorImplementation) {
reporter.reportOn(propertySource, FirErrors.MUST_BE_INITIALIZED, context)
} else {
reporter.reportOn(propertySource, FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT, context)
}
reportMustBeInitialized(property, isDefinitelyAssignedInConstructor, containingClass, propertySource, reporter, context)
}
}
if (property.isLateInit) {
@@ -175,6 +171,30 @@ internal fun checkPropertyInitializer(
}
}
private fun reportMustBeInitialized(
property: FirProperty,
isDefinitelyAssignedInConstructor: Boolean,
containingClass: FirClass?,
propertySource: KtSourceElement,
reporter: DiagnosticReporter,
context: CheckerContext,
) {
check(!property.isAbstract) { "${::reportMustBeInitialized.name} isn't called for abstract properties" }
val suggestMakingItFinal = containingClass != null &&
!property.hasSetterAccessorImplementation &&
property.getEffectiveModality(containingClass, context.languageVersionSettings) != Modality.FINAL &&
isDefinitelyAssignedInConstructor
val suggestMakingItAbstract = containingClass != null && !property.hasAnyAccessorImplementation
val factory = when {
suggestMakingItFinal && suggestMakingItAbstract -> FirErrors.MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT
suggestMakingItFinal -> FirErrors.MUST_BE_INITIALIZED_OR_BE_FINAL
suggestMakingItAbstract -> FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT
else -> FirErrors.MUST_BE_INITIALIZED
}
reporter.reportOn(propertySource, factory, context)
}
private val FirPropertyAccessor?.hasImplementation: Boolean
get() = (this !is FirDefaultPropertyAccessor && this?.hasBody == true)
private val FirProperty.hasSetterAccessorImplementation: Boolean
@@ -337,6 +337,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_VARARG_P
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTI_FIELD_VALUE_CLASS_PRIMARY_CONSTRUCTOR_DEFAULT_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_BE_FINAL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NAMED_ARGUMENTS_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NAMED_PARAMETER_NOT_FOUND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NAME_FOR_AMBIGUOUS_PARAMETER
@@ -1629,7 +1631,10 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
map.put(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM, "Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly")
map.put(MUST_BE_INITIALIZED, "Property must be initialized")
map.put(MUST_BE_INITIALIZED_OR_BE_FINAL, "Property must be initialized or be final")
map.put(MUST_BE_INITIALIZED_OR_BE_ABSTRACT, "Property must be initialized or be abstract")
map.put(MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT, "Property must be initialized, be final, or be abstract");
map.put(EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT, "Extension property must have accessors or be abstract")
map.put(UNNECESSARY_LATEINIT, "Lateinit is unnecessary: definitely initialized in constructors")
@@ -653,8 +653,13 @@ class ControlFlowInformationProviderImpl private constructor(
val initializers = initializersMap[pseudocode.exitInstruction] ?: return
val declaredVariables = pseudocodeVariablesData.getDeclaredVariables(pseudocode, false)
for (variable in declaredVariables) {
// - If we have a primary constructor and several secondary constructors then the `if` below is called only once for the primary
// constructor/init block
// - If we have several secondary constructors without a primary constructor then the `if` below is called each time for every
// secondary constructor. (init block is considered as part of each secondary constructor in that case)
if (variable is PropertyDescriptor) {
if (initializers.incoming.getOrNull(variable)?.definitelyInitialized() == true) continue
trace.record(IS_DEFINITELY_NOT_ASSIGNED_IN_CONSTRUCTOR, variable)
trace.record(IS_UNINITIALIZED, variable)
}
}
@@ -1472,10 +1477,3 @@ class ControlFlowInformationProviderImpl private constructor(
return result
}
}
private fun PropertyDescriptor.getEffectiveModality(languageVersionSettings: LanguageVersionSettings): Modality =
when (languageVersionSettings.supportsFeature(LanguageFeature.TakeIntoAccountEffectivelyFinalInMustBeInitializedCheck) &&
modality == Modality.OPEN && (containingDeclaration as? ClassDescriptor)?.modality == Modality.FINAL) {
true -> Modality.FINAL
false -> modality
}
@@ -673,7 +673,9 @@ public interface Errors {
DiagnosticFactory0<KtProperty> PROPERTY_WITH_NO_TYPE_NO_INITIALIZER = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory0<KtProperty> MUST_BE_INITIALIZED = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory0<KtProperty> MUST_BE_INITIALIZED_OR_BE_FINAL = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory0<KtProperty> MUST_BE_INITIALIZED_OR_BE_ABSTRACT = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory0<KtProperty> MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory0<KtProperty> EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT =
DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
DiagnosticFactory0<KtProperty> UNNECESSARY_LATEINIT = DiagnosticFactory0.create(WARNING, LATEINIT_MODIFIER);
@@ -306,7 +306,9 @@ public class DefaultErrorMessages {
MAP.put(PRIVATE_SETTER_FOR_OPEN_PROPERTY, "Private setters are not allowed for open properties");
MAP.put(BACKING_FIELD_IN_INTERFACE, "Property in an interface cannot have a backing field");
MAP.put(MUST_BE_INITIALIZED, "Property must be initialized");
MAP.put(MUST_BE_INITIALIZED_OR_BE_FINAL, "Property must be initialized or be final");
MAP.put(MUST_BE_INITIALIZED_OR_BE_ABSTRACT, "Property must be initialized or be abstract");
MAP.put(MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT, "Property must be initialized, be final, or be abstract");
MAP.put(EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT, "Extension property must have accessors or be abstract");
MAP.put(UNNECESSARY_LATEINIT, "Lateinit is unnecessary: definitely initialized in constructors");
MAP.put(PROPERTY_INITIALIZER_IN_INTERFACE, "Property initializers are not allowed in interfaces");
@@ -224,6 +224,7 @@ public interface BindingContext {
}
};
WritableSlice<PropertyDescriptor, Boolean> IS_UNINITIALIZED = Slices.createSimpleSetSlice();
WritableSlice<PropertyDescriptor, Boolean> IS_DEFINITELY_NOT_ASSIGNED_IN_CONSTRUCTOR = Slices.createSimpleSetSlice();
WritableSlice<PropertyDescriptor, Boolean> MUST_BE_LATEINIT = Slices.createSimpleSetSlice();
WritableSlice<KtLambdaExpression, EventOccurrencesRange> LAMBDA_INVOCATIONS = Slices.createSimpleSlice();
@@ -694,7 +694,7 @@ class DeclarationsChecker(
}
private fun checkPropertyInitializer(property: KtProperty, propertyDescriptor: PropertyDescriptor) {
val hasAccessorImplementation = propertyDescriptor.hasAccessorImplementation()
val hasAnyAccessorImplementation = propertyDescriptor.hasAnyAccessorImplementation()
val containingDeclaration = propertyDescriptor.containingDeclaration
val inInterface = DescriptorUtils.isInterface(containingDeclaration)
@@ -709,7 +709,7 @@ class DeclarationsChecker(
}
val backingFieldRequired = trace.bindingContext.get(BACKING_FIELD_REQUIRED, propertyDescriptor) ?: false
if (inInterface && backingFieldRequired && hasAccessorImplementation) {
if (inInterface && backingFieldRequired && hasAnyAccessorImplementation) {
trace.report(BACKING_FIELD_IN_INTERFACE.on(property))
}
@@ -772,14 +772,10 @@ class DeclarationsChecker(
val isUninitialized = trace.bindingContext.get(IS_UNINITIALIZED, propertyDescriptor) ?: false
val isExternal = propertyDescriptor.isEffectivelyExternal()
if (backingFieldRequired && !inInterface && !propertyDescriptor.isLateInit && !isExpect && isUninitialized && !isExternal) {
if (propertyDescriptor.extensionReceiverParameter != null && !hasAccessorImplementation) {
if (propertyDescriptor.extensionReceiverParameter != null && !hasAnyAccessorImplementation) {
trace.report(EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT.on(property))
} else if (diagnosticSuppressor.shouldReportNoBody(propertyDescriptor)) {
if (containingDeclaration !is ClassDescriptor || hasAccessorImplementation) {
trace.report(MUST_BE_INITIALIZED.on(property))
} else {
trace.report(MUST_BE_INITIALIZED_OR_BE_ABSTRACT.on(property))
}
reportMustBeInitialized(propertyDescriptor, containingDeclaration, hasAnyAccessorImplementation, property, trace)
}
} else if (property.typeReference == null && !languageVersionSettings.supportsFeature(LanguageFeature.ShortSyntaxForPropertyGetters)) {
trace.report(
@@ -803,6 +799,30 @@ class DeclarationsChecker(
}
}
private fun reportMustBeInitialized(
propertyDescriptor: PropertyDescriptor,
containingDeclaration: DeclarationDescriptor,
hasAnyAccessorImplementation: Boolean,
property: KtProperty,
trace: BindingTrace,
) {
check(propertyDescriptor.getEffectiveModality(languageVersionSettings) != Modality.ABSTRACT) {
"${::reportMustBeInitialized.name} isn't called for abstract properties"
}
val suggestMakingItFinal = containingDeclaration is ClassDescriptor &&
!propertyDescriptor.hasSetterAccessorImplementation() &&
propertyDescriptor.getEffectiveModality(languageVersionSettings) != Modality.FINAL &&
trace.bindingContext.get(IS_DEFINITELY_NOT_ASSIGNED_IN_CONSTRUCTOR, propertyDescriptor) == false
val suggestMakingItAbstract = containingDeclaration is ClassDescriptor && !hasAnyAccessorImplementation
when {
suggestMakingItFinal && suggestMakingItAbstract -> trace.report(MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT.on(property))
suggestMakingItFinal -> trace.report(MUST_BE_INITIALIZED_OR_BE_FINAL.on(property))
suggestMakingItAbstract -> trace.report(MUST_BE_INITIALIZED_OR_BE_ABSTRACT.on(property))
else -> trace.report(MUST_BE_INITIALIZED.on(property))
}
}
private fun noExplicitTypeOrGetterType(property: KtProperty) =
property.typeReference == null
&& (property.getter == null || (property.getter!!.hasBlockBody() && property.getter!!.returnTypeReference == null))
@@ -1067,10 +1087,14 @@ class DeclarationsChecker(
return !modifierList.hasModifier(KtTokens.OVERRIDE_KEYWORD)
}
fun PropertyDescriptor.hasAccessorImplementation(): Boolean {
getter?.let { if (it.hasBody()) return true }
setter?.let { if (it.hasBody()) return true }
return false
}
private fun PropertyDescriptor.hasSetterAccessorImplementation(): Boolean = setter?.hasBody() == true
fun PropertyDescriptor.hasAnyAccessorImplementation(): Boolean = hasSetterAccessorImplementation() || getter?.hasBody() == true
}
}
fun PropertyDescriptor.getEffectiveModality(languageVersionSettings: LanguageVersionSettings): Modality =
when (languageVersionSettings.supportsFeature(LanguageFeature.TakeIntoAccountEffectivelyFinalInMustBeInitializedCheck) &&
modality == Modality.OPEN && (containingDeclaration as? ClassDescriptor)?.modality == Modality.FINAL) {
true -> Modality.FINAL
false -> modality
}
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.UnsignedTypes
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassDescriptor
@@ -30,7 +29,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.resolve.DeclarationsChecker.Companion.hasAccessorImplementation
import org.jetbrains.kotlin.resolve.DeclarationsChecker.Companion.hasAnyAccessorImplementation
import org.jetbrains.kotlin.resolve.descriptorUtil.inlineClassRepresentation
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
@@ -108,7 +107,7 @@ object LateinitModifierApplicabilityChecker {
if (descriptor is PropertyDescriptor) {
val isAbstract = descriptor.modality == Modality.ABSTRACT
val hasDelegateExpressionOrInitializer = ktDeclaration is KtProperty && ktDeclaration.hasDelegateExpressionOrInitializer()
val hasAccessorImplementation = descriptor.hasAccessorImplementation()
val hasAccessorImplementation = descriptor.hasAnyAccessorImplementation()
val hasBackingField = trace.bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor) ?: false
if (ktDeclaration is KtParameter) {
@@ -2,7 +2,7 @@ abstract class My(val v: Int) {
// Ok: variable is just abstract
abstract var x: Int
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open var y: Int<!>
<!MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT!>open var y: Int<!>
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open var z: Int<!>
@@ -2,7 +2,7 @@ abstract class My(val v: Int) {
// Ok: variable is just abstract
abstract var x: Int
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open var y: Int<!>
<!MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT!>open var y: Int<!>
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open var z: Int<!>
@@ -5,7 +5,7 @@ open class Base {
}
class Foo : Base() {
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>override var x: String<!>
<!MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT!>override var x: String<!>
init {
x = ""
@@ -11,7 +11,7 @@ open class Foo {
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_FINAL_OR_ABSTRACT!>open val b0: Int<!>
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open val f0: Int<!>
open val d0: Int = 1
@@ -19,7 +19,7 @@ open class Foo {
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_OR_BE_FINAL!>open val b1: Int<!>; get() = field
<!MUST_BE_INITIALIZED!>open val f1: Int<!>; get() = field
open val d1: Int = 1; get() = field
@@ -27,7 +27,7 @@ open class Foo {
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_FINAL_OR_ABSTRACT!>open val b2: Int<!>; get
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open val f2: Int<!>; get
open val d2: Int = 1; get
@@ -13,28 +13,28 @@ open class Foo {
var a00: Int; <!MUST_BE_INITIALIZED!>var a01: Int<!>; set(v) { field = v }; var a02: Int; set; <!MUST_BE_INITIALIZED!>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) {};
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open var b00: Int<!>; <!MUST_BE_INITIALIZED!>open var b01: Int<!>; set(v) { field = v }; <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open var b02: Int<!>; set; <!MUST_BE_INITIALIZED!>open var b03: Int<!>; set(v) {};
<!MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT!>open var b00: Int<!>; <!MUST_BE_INITIALIZED!>open var b01: Int<!>; set(v) { field = v }; <!MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT!>open var b02: Int<!>; set; <!MUST_BE_INITIALIZED!>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; <!MUST_BE_INITIALIZED!>var a11: Int<!>; set(v) { field = v } get() = field; var a12: Int; set get() = field; <!MUST_BE_INITIALIZED!>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;
<!MUST_BE_INITIALIZED!>open var b10: Int<!>; get() = field; <!MUST_BE_INITIALIZED!>open var b11: Int<!>; set(v) { field = v } get() = field; <!MUST_BE_INITIALIZED!>open var b12: Int<!>; set get() = field; <!MUST_BE_INITIALIZED!>open var b13: Int<!>; set(v) {} get() = field;
<!MUST_BE_INITIALIZED_OR_BE_FINAL!>open var b10: Int<!>; get() = field; <!MUST_BE_INITIALIZED!>open var b11: Int<!>; set(v) { field = v } get() = field; <!MUST_BE_INITIALIZED_OR_BE_FINAL!>open var b12: Int<!>; set get() = field; <!MUST_BE_INITIALIZED!>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; <!MUST_BE_INITIALIZED!>var a21: Int<!>; set(v) { field = v } get; var a22: Int; set get; <!MUST_BE_INITIALIZED!>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;
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open var b20: Int<!>; get; <!MUST_BE_INITIALIZED!>open var b21: Int<!>; set(v) { field = v } get; <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open var b22: Int<!>; set get; <!MUST_BE_INITIALIZED!>open var b23: Int<!>; set(v) {} get;
<!MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT!>open var b20: Int<!>; get; <!MUST_BE_INITIALIZED!>open var b21: Int<!>; set(v) { field = v } get; <!MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT!>open var b22: Int<!>; set get; <!MUST_BE_INITIALIZED!>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; <!MUST_BE_INITIALIZED!>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;
<!MUST_BE_INITIALIZED!>open var b30: Int<!>; get() = 1; <!MUST_BE_INITIALIZED!>open var b31: Int<!>; set(v) { field = v } get() = 1; <!MUST_BE_INITIALIZED!>open var b32: Int<!>; set get() = 1; open var b33: Int; set(v) {} get() = 1;
<!MUST_BE_INITIALIZED_OR_BE_FINAL!>open var b30: Int<!>; get() = 1; <!MUST_BE_INITIALIZED!>open var b31: Int<!>; set(v) { field = v } get() = 1; <!MUST_BE_INITIALIZED_OR_BE_FINAL!>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;