[FE] Prohibit open val deferred initialization
^KT-57553 Fixed Review: https://jetbrains.team/p/kt/reviews/9967 Other related tests: - testUninitializedOrReassignedVariables - testUseOfPropertiesWithoutPrimary - @TestMetadata("compiler/testData/diagnostics/tests/secondaryConstructors") - testAugmentedAssignmentInInitializer - testInitOpenSetter - testInitOverrideInConstructorComplex - testPropertyInitializationOrder
This commit is contained in:
+12
@@ -2857,6 +2857,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.MUST_BE_INITIALIZED_OR_BE_FINAL_WARNING) { firDiagnostic ->
|
||||||
|
MustBeInitializedOrBeFinalWarningImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT) { firDiagnostic ->
|
add(FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT) { firDiagnostic ->
|
||||||
MustBeInitializedOrBeAbstractImpl(
|
MustBeInitializedOrBeAbstractImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
@@ -2869,6 +2875,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT_WARNING) { firDiagnostic ->
|
||||||
|
MustBeInitializedOrFinalOrAbstractWarningImpl(
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT) { firDiagnostic ->
|
add(FirErrors.EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT) { firDiagnostic ->
|
||||||
ExtensionPropertyMustHaveAccessorsOrBeAbstractImpl(
|
ExtensionPropertyMustHaveAccessorsOrBeAbstractImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+8
@@ -2023,6 +2023,10 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = MustBeInitializedOrBeFinal::class
|
override val diagnosticClass get() = MustBeInitializedOrBeFinal::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class MustBeInitializedOrBeFinalWarning : KtFirDiagnostic<KtProperty>() {
|
||||||
|
override val diagnosticClass get() = MustBeInitializedOrBeFinalWarning::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class MustBeInitializedOrBeAbstract : KtFirDiagnostic<KtProperty>() {
|
abstract class MustBeInitializedOrBeAbstract : KtFirDiagnostic<KtProperty>() {
|
||||||
override val diagnosticClass get() = MustBeInitializedOrBeAbstract::class
|
override val diagnosticClass get() = MustBeInitializedOrBeAbstract::class
|
||||||
}
|
}
|
||||||
@@ -2031,6 +2035,10 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = MustBeInitializedOrFinalOrAbstract::class
|
override val diagnosticClass get() = MustBeInitializedOrFinalOrAbstract::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class MustBeInitializedOrFinalOrAbstractWarning : KtFirDiagnostic<KtProperty>() {
|
||||||
|
override val diagnosticClass get() = MustBeInitializedOrFinalOrAbstractWarning::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class ExtensionPropertyMustHaveAccessorsOrBeAbstract : KtFirDiagnostic<KtProperty>() {
|
abstract class ExtensionPropertyMustHaveAccessorsOrBeAbstract : KtFirDiagnostic<KtProperty>() {
|
||||||
override val diagnosticClass get() = ExtensionPropertyMustHaveAccessorsOrBeAbstract::class
|
override val diagnosticClass get() = ExtensionPropertyMustHaveAccessorsOrBeAbstract::class
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -2430,6 +2430,11 @@ internal class MustBeInitializedOrBeFinalImpl(
|
|||||||
override val token: KtLifetimeToken,
|
override val token: KtLifetimeToken,
|
||||||
) : KtFirDiagnostic.MustBeInitializedOrBeFinal(), KtAbstractFirDiagnostic<KtProperty>
|
) : KtFirDiagnostic.MustBeInitializedOrBeFinal(), KtAbstractFirDiagnostic<KtProperty>
|
||||||
|
|
||||||
|
internal class MustBeInitializedOrBeFinalWarningImpl(
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: KtLifetimeToken,
|
||||||
|
) : KtFirDiagnostic.MustBeInitializedOrBeFinalWarning(), KtAbstractFirDiagnostic<KtProperty>
|
||||||
|
|
||||||
internal class MustBeInitializedOrBeAbstractImpl(
|
internal class MustBeInitializedOrBeAbstractImpl(
|
||||||
override val firDiagnostic: KtPsiDiagnostic,
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
override val token: KtLifetimeToken,
|
override val token: KtLifetimeToken,
|
||||||
@@ -2440,6 +2445,11 @@ internal class MustBeInitializedOrFinalOrAbstractImpl(
|
|||||||
override val token: KtLifetimeToken,
|
override val token: KtLifetimeToken,
|
||||||
) : KtFirDiagnostic.MustBeInitializedOrFinalOrAbstract(), KtAbstractFirDiagnostic<KtProperty>
|
) : KtFirDiagnostic.MustBeInitializedOrFinalOrAbstract(), KtAbstractFirDiagnostic<KtProperty>
|
||||||
|
|
||||||
|
internal class MustBeInitializedOrFinalOrAbstractWarningImpl(
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: KtLifetimeToken,
|
||||||
|
) : KtFirDiagnostic.MustBeInitializedOrFinalOrAbstractWarning(), KtAbstractFirDiagnostic<KtProperty>
|
||||||
|
|
||||||
internal class ExtensionPropertyMustHaveAccessorsOrBeAbstractImpl(
|
internal class ExtensionPropertyMustHaveAccessorsOrBeAbstractImpl(
|
||||||
override val firDiagnostic: KtPsiDiagnostic,
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
override val token: KtLifetimeToken,
|
override val token: KtLifetimeToken,
|
||||||
|
|||||||
+27
-3
@@ -2984,6 +2984,24 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt");
|
runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitSecondaryConstructorErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitSecondaryConstructorErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitSecondaryConstructorErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("SetterWithExplicitType.kt")
|
@TestMetadata("SetterWithExplicitType.kt")
|
||||||
public void testSetterWithExplicitType() throws Exception {
|
public void testSetterWithExplicitType() throws Exception {
|
||||||
@@ -2997,9 +3015,15 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("ValDeferredInitInOpenClass.kt")
|
@TestMetadata("ValDeferredInitInOpenClassOpenValError.kt")
|
||||||
public void testValDeferredInitInOpenClass() throws Exception {
|
public void testValDeferredInitInOpenClassOpenValError() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClass.kt");
|
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClassOpenValError.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("ValDeferredInitInOpenClassOpenValWarning.kt")
|
||||||
|
public void testValDeferredInitInOpenClassOpenValWarning() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClassOpenValWarning.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+27
-3
@@ -2984,6 +2984,24 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
|||||||
runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt");
|
runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitSecondaryConstructorErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitSecondaryConstructorErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitSecondaryConstructorErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("SetterWithExplicitType.kt")
|
@TestMetadata("SetterWithExplicitType.kt")
|
||||||
public void testSetterWithExplicitType() throws Exception {
|
public void testSetterWithExplicitType() throws Exception {
|
||||||
@@ -2997,9 +3015,15 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("ValDeferredInitInOpenClass.kt")
|
@TestMetadata("ValDeferredInitInOpenClassOpenValError.kt")
|
||||||
public void testValDeferredInitInOpenClass() throws Exception {
|
public void testValDeferredInitInOpenClassOpenValError() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClass.kt");
|
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClassOpenValError.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("ValDeferredInitInOpenClassOpenValWarning.kt")
|
||||||
|
public void testValDeferredInitInOpenClassOpenValWarning() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClassOpenValWarning.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+27
-3
@@ -2984,6 +2984,24 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
|||||||
runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt");
|
runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitSecondaryConstructorErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitSecondaryConstructorErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitSecondaryConstructorErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("SetterWithExplicitType.kt")
|
@TestMetadata("SetterWithExplicitType.kt")
|
||||||
public void testSetterWithExplicitType() throws Exception {
|
public void testSetterWithExplicitType() throws Exception {
|
||||||
@@ -2997,9 +3015,15 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("ValDeferredInitInOpenClass.kt")
|
@TestMetadata("ValDeferredInitInOpenClassOpenValError.kt")
|
||||||
public void testValDeferredInitInOpenClass() throws Exception {
|
public void testValDeferredInitInOpenClassOpenValError() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClass.kt");
|
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClassOpenValError.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("ValDeferredInitInOpenClassOpenValWarning.kt")
|
||||||
|
public void testValDeferredInitInOpenClassOpenValWarning() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClassOpenValWarning.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+27
-3
@@ -2990,6 +2990,24 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt");
|
runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitSecondaryConstructorErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitSecondaryConstructorErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitSecondaryConstructorErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("SetterWithExplicitType.kt")
|
@TestMetadata("SetterWithExplicitType.kt")
|
||||||
public void testSetterWithExplicitType() throws Exception {
|
public void testSetterWithExplicitType() throws Exception {
|
||||||
@@ -3003,9 +3021,15 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("ValDeferredInitInOpenClass.kt")
|
@TestMetadata("ValDeferredInitInOpenClassOpenValError.kt")
|
||||||
public void testValDeferredInitInOpenClass() throws Exception {
|
public void testValDeferredInitInOpenClassOpenValError() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClass.kt");
|
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClassOpenValError.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("ValDeferredInitInOpenClassOpenValWarning.kt")
|
||||||
|
public void testValDeferredInitInOpenClassOpenValWarning() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClassOpenValWarning.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+2
@@ -1010,8 +1010,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
|
|
||||||
val MUST_BE_INITIALIZED 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_FINAL by error<KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
|
||||||
|
val MUST_BE_INITIALIZED_OR_BE_FINAL_WARNING by warning<KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
|
||||||
val MUST_BE_INITIALIZED_OR_BE_ABSTRACT 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 MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT by error<KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
|
||||||
|
val MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT_WARNING by warning<KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
|
||||||
|
|
||||||
val EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_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)
|
val UNNECESSARY_LATEINIT by warning<KtProperty>(PositioningStrategy.LATEINIT_MODIFIER)
|
||||||
|
|||||||
@@ -534,8 +534,10 @@ object FirErrors {
|
|||||||
val PROPERTY_WITH_NO_TYPE_NO_INITIALIZER by error0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
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 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_FINAL by error0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||||
|
val MUST_BE_INITIALIZED_OR_BE_FINAL_WARNING by warning0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||||
val MUST_BE_INITIALIZED_OR_BE_ABSTRACT 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 MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT by error0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||||
|
val MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT_WARNING by warning0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||||
val EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_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 UNNECESSARY_LATEINIT by warning0<KtProperty>(SourceElementPositioningStrategies.LATEINIT_MODIFIER)
|
||||||
val BACKING_FIELD_IN_INTERFACE by error0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
val BACKING_FIELD_IN_INTERFACE by error0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||||
|
|||||||
+20
-4
@@ -185,12 +185,28 @@ private fun reportMustBeInitialized(
|
|||||||
property.getEffectiveModality(containingClass, context.languageVersionSettings) != Modality.FINAL &&
|
property.getEffectiveModality(containingClass, context.languageVersionSettings) != Modality.FINAL &&
|
||||||
isDefinitelyAssignedInConstructor
|
isDefinitelyAssignedInConstructor
|
||||||
val suggestMakingItAbstract = containingClass != null && !property.hasAnyAccessorImplementation
|
val suggestMakingItAbstract = containingClass != null && !property.hasAnyAccessorImplementation
|
||||||
|
val isOpenValDeferredInitDeprecationWarning =
|
||||||
|
!context.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitOpenValDeferredInitialization) &&
|
||||||
|
property.getEffectiveModality(containingClass, context.languageVersionSettings) == Modality.OPEN && property.isVal &&
|
||||||
|
isDefinitelyAssignedInConstructor
|
||||||
|
|
||||||
val factory = when {
|
val factory = when {
|
||||||
suggestMakingItFinal && suggestMakingItAbstract -> FirErrors.MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT
|
suggestMakingItFinal && suggestMakingItAbstract -> when (isOpenValDeferredInitDeprecationWarning) {
|
||||||
suggestMakingItFinal -> FirErrors.MUST_BE_INITIALIZED_OR_BE_FINAL
|
true -> FirErrors.MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT_WARNING
|
||||||
suggestMakingItAbstract -> FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT
|
false -> FirErrors.MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT
|
||||||
else -> FirErrors.MUST_BE_INITIALIZED
|
}
|
||||||
|
suggestMakingItFinal -> when (isOpenValDeferredInitDeprecationWarning) {
|
||||||
|
true -> FirErrors.MUST_BE_INITIALIZED_OR_BE_FINAL_WARNING
|
||||||
|
false -> FirErrors.MUST_BE_INITIALIZED_OR_BE_FINAL
|
||||||
|
}
|
||||||
|
suggestMakingItAbstract -> when (isOpenValDeferredInitDeprecationWarning) {
|
||||||
|
true -> error("Not reachable case. Every \"open val + deferred init\" case that could be made `abstract`, also could be made `final`")
|
||||||
|
false -> FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT
|
||||||
|
}
|
||||||
|
else -> when (isOpenValDeferredInitDeprecationWarning) {
|
||||||
|
true -> error("Not reachable case. We can always suggest making `open val` property `final`")
|
||||||
|
false -> FirErrors.MUST_BE_INITIALIZED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
reporter.reportOn(propertySource, factory, context)
|
reporter.reportOn(propertySource, factory, context)
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -338,7 +338,9 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTI_FIELD_VALUE
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED
|
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_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_BE_FINAL
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_BE_FINAL_WARNING
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT_WARNING
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NAMED_ARGUMENTS_NOT_ALLOWED
|
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.NAMED_PARAMETER_NOT_FOUND
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NAME_FOR_AMBIGUOUS_PARAMETER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NAME_FOR_AMBIGUOUS_PARAMETER
|
||||||
@@ -1632,8 +1634,10 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
|
|
||||||
map.put(MUST_BE_INITIALIZED, "Property must be initialized")
|
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_FINAL, "Property must be initialized or be final")
|
||||||
|
map.put(MUST_BE_INITIALIZED_OR_BE_FINAL_WARNING, "Property must be initialized or be final. This warning will become an error in future releases.")
|
||||||
map.put(MUST_BE_INITIALIZED_OR_BE_ABSTRACT, "Property must be initialized or be abstract")
|
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(MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT, "Property must be initialized, be final, or be abstract")
|
||||||
|
map.put(MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT_WARNING, "Property must be initialized, be final, or be abstract. This warning will become an error in future releases.")
|
||||||
|
|
||||||
map.put(EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT, "Extension property must have accessors 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(UNNECESSARY_LATEINIT, "Lateinit is unnecessary: definitely initialized in constructors")
|
||||||
|
|||||||
-1
@@ -619,7 +619,6 @@ class ControlFlowInformationProviderImpl private constructor(
|
|||||||
if (variableDescriptor !is PropertyDescriptor
|
if (variableDescriptor !is PropertyDescriptor
|
||||||
|| ctxt.enterInitState?.mayBeInitialized() == true
|
|| ctxt.enterInitState?.mayBeInitialized() == true
|
||||||
|| ctxt.exitInitState?.mayBeInitialized() != true
|
|| ctxt.exitInitState?.mayBeInitialized() != true
|
||||||
|| !variableDescriptor.isVar
|
|
||||||
|| trace.get(BACKING_FIELD_REQUIRED, variableDescriptor) != true
|
|| trace.get(BACKING_FIELD_REQUIRED, variableDescriptor) != true
|
||||||
) {
|
) {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -674,8 +674,11 @@ public interface Errors {
|
|||||||
|
|
||||||
DiagnosticFactory0<KtProperty> MUST_BE_INITIALIZED = 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_FINAL = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||||
|
DiagnosticFactory0<KtProperty> MUST_BE_INITIALIZED_OR_BE_FINAL_WARNING = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE);
|
||||||
DiagnosticFactory0<KtProperty> MUST_BE_INITIALIZED_OR_BE_ABSTRACT = 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> MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||||
|
DiagnosticFactory0<KtProperty> MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT_WARNING = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE);
|
||||||
|
|
||||||
DiagnosticFactory0<KtProperty> EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT =
|
DiagnosticFactory0<KtProperty> EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT =
|
||||||
DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||||
DiagnosticFactory0<KtProperty> UNNECESSARY_LATEINIT = DiagnosticFactory0.create(WARNING, LATEINIT_MODIFIER);
|
DiagnosticFactory0<KtProperty> UNNECESSARY_LATEINIT = DiagnosticFactory0.create(WARNING, LATEINIT_MODIFIER);
|
||||||
|
|||||||
+4
@@ -305,10 +305,14 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY, "Private setters are not allowed for abstract properties");
|
MAP.put(PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY, "Private setters are not allowed for abstract properties");
|
||||||
MAP.put(PRIVATE_SETTER_FOR_OPEN_PROPERTY, "Private setters are not allowed for open properties");
|
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(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, "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_FINAL, "Property must be initialized or be final");
|
||||||
|
MAP.put(MUST_BE_INITIALIZED_OR_BE_FINAL_WARNING, "Property must be initialized or be final. This warning will become an error in future releases.");
|
||||||
MAP.put(MUST_BE_INITIALIZED_OR_BE_ABSTRACT, "Property must be initialized or be abstract");
|
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(MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT, "Property must be initialized, be final, or be abstract");
|
||||||
|
MAP.put(MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT_WARNING, "Property must be initialized, be final, or be abstract. This warning will become an error in future releases.");
|
||||||
|
|
||||||
MAP.put(EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT, "Extension property must have accessors 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(UNNECESSARY_LATEINIT, "Lateinit is unnecessary: definitely initialized in constructors");
|
||||||
MAP.put(PROPERTY_INITIALIZER_IN_INTERFACE, "Property initializers are not allowed in interfaces");
|
MAP.put(PROPERTY_INITIALIZER_IN_INTERFACE, "Property initializers are not allowed in interfaces");
|
||||||
|
|||||||
@@ -775,7 +775,14 @@ class DeclarationsChecker(
|
|||||||
if (propertyDescriptor.extensionReceiverParameter != null && !hasAnyAccessorImplementation) {
|
if (propertyDescriptor.extensionReceiverParameter != null && !hasAnyAccessorImplementation) {
|
||||||
trace.report(EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT.on(property))
|
trace.report(EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT.on(property))
|
||||||
} else if (diagnosticSuppressor.shouldReportNoBody(propertyDescriptor)) {
|
} else if (diagnosticSuppressor.shouldReportNoBody(propertyDescriptor)) {
|
||||||
reportMustBeInitialized(propertyDescriptor, containingDeclaration, hasAnyAccessorImplementation, property, trace)
|
reportMustBeInitialized(
|
||||||
|
propertyDescriptor,
|
||||||
|
containingDeclaration,
|
||||||
|
hasAnyAccessorImplementation,
|
||||||
|
property,
|
||||||
|
languageVersionSettings,
|
||||||
|
trace
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else if (property.typeReference == null && !languageVersionSettings.supportsFeature(LanguageFeature.ShortSyntaxForPropertyGetters)) {
|
} else if (property.typeReference == null && !languageVersionSettings.supportsFeature(LanguageFeature.ShortSyntaxForPropertyGetters)) {
|
||||||
trace.report(
|
trace.report(
|
||||||
@@ -804,6 +811,7 @@ class DeclarationsChecker(
|
|||||||
containingDeclaration: DeclarationDescriptor,
|
containingDeclaration: DeclarationDescriptor,
|
||||||
hasAnyAccessorImplementation: Boolean,
|
hasAnyAccessorImplementation: Boolean,
|
||||||
property: KtProperty,
|
property: KtProperty,
|
||||||
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
) {
|
) {
|
||||||
check(propertyDescriptor.getEffectiveModality(languageVersionSettings) != Modality.ABSTRACT) {
|
check(propertyDescriptor.getEffectiveModality(languageVersionSettings) != Modality.ABSTRACT) {
|
||||||
@@ -814,13 +822,31 @@ class DeclarationsChecker(
|
|||||||
propertyDescriptor.getEffectiveModality(languageVersionSettings) != Modality.FINAL &&
|
propertyDescriptor.getEffectiveModality(languageVersionSettings) != Modality.FINAL &&
|
||||||
trace.bindingContext.get(IS_DEFINITELY_NOT_ASSIGNED_IN_CONSTRUCTOR, propertyDescriptor) == false
|
trace.bindingContext.get(IS_DEFINITELY_NOT_ASSIGNED_IN_CONSTRUCTOR, propertyDescriptor) == false
|
||||||
val suggestMakingItAbstract = containingDeclaration is ClassDescriptor && !hasAnyAccessorImplementation
|
val suggestMakingItAbstract = containingDeclaration is ClassDescriptor && !hasAnyAccessorImplementation
|
||||||
|
val isOpenValDeferredInitDeprecationWarning =
|
||||||
|
!languageVersionSettings.supportsFeature(LanguageFeature.ProhibitOpenValDeferredInitialization) &&
|
||||||
|
propertyDescriptor.getEffectiveModality(languageVersionSettings) == Modality.OPEN &&
|
||||||
|
!propertyDescriptor.isVar &&
|
||||||
|
trace.bindingContext.get(IS_DEFINITELY_NOT_ASSIGNED_IN_CONSTRUCTOR, propertyDescriptor) == false
|
||||||
|
|
||||||
when {
|
val factory = when {
|
||||||
suggestMakingItFinal && suggestMakingItAbstract -> trace.report(MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT.on(property))
|
suggestMakingItFinal && suggestMakingItAbstract -> when (isOpenValDeferredInitDeprecationWarning) {
|
||||||
suggestMakingItFinal -> trace.report(MUST_BE_INITIALIZED_OR_BE_FINAL.on(property))
|
true -> MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT_WARNING
|
||||||
suggestMakingItAbstract -> trace.report(MUST_BE_INITIALIZED_OR_BE_ABSTRACT.on(property))
|
false -> MUST_BE_INITIALIZED_OR_FINAL_OR_ABSTRACT
|
||||||
else -> trace.report(MUST_BE_INITIALIZED.on(property))
|
}
|
||||||
|
suggestMakingItFinal -> when (isOpenValDeferredInitDeprecationWarning) {
|
||||||
|
true -> MUST_BE_INITIALIZED_OR_BE_FINAL_WARNING
|
||||||
|
false -> MUST_BE_INITIALIZED_OR_BE_FINAL
|
||||||
|
}
|
||||||
|
suggestMakingItAbstract -> when (isOpenValDeferredInitDeprecationWarning) {
|
||||||
|
true -> error("Not reachable case. Every \"open val + deferred init\" case that could be made `abstract`, also could be made `final`")
|
||||||
|
false -> MUST_BE_INITIALIZED_OR_BE_ABSTRACT
|
||||||
|
}
|
||||||
|
else -> when (isOpenValDeferredInitDeprecationWarning) {
|
||||||
|
true -> error("Not reachable case. We can always suggest making `open val` property `final`")
|
||||||
|
false -> MUST_BE_INITIALIZED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
trace.report(factory.on(property))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun noExplicitTypeOrGetterType(property: KtProperty) =
|
private fun noExplicitTypeOrGetterType(property: KtProperty) =
|
||||||
|
|||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// !LANGUAGE: -ProhibitOpenValDeferredInitialization
|
||||||
abstract class A {
|
abstract class A {
|
||||||
val b = B("O")
|
val b = B("O")
|
||||||
|
|
||||||
|
|||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// !DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS
|
||||||
|
// !LANGUAGE:-ProhibitOpenValDeferredInitialization
|
||||||
|
open class Foo {
|
||||||
|
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open val foo: Int<!>
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (1 != 1) {
|
||||||
|
foo = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// !DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS
|
||||||
|
// !LANGUAGE:-ProhibitOpenValDeferredInitialization
|
||||||
|
open class Foo {
|
||||||
|
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open val foo: Int<!>
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
if (1 != 1) {
|
||||||
|
foo = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// !DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS
|
||||||
|
// !LANGUAGE:-ProhibitOpenValDeferredInitialization
|
||||||
|
open class Foo {
|
||||||
|
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>open val foo: Int<!>
|
||||||
|
|
||||||
|
constructor(x: Int) {}
|
||||||
|
constructor() {
|
||||||
|
foo = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
-18
@@ -9,28 +9,28 @@
|
|||||||
// d = open + initialized in place
|
// d = open + initialized in place
|
||||||
class Foo : I {
|
class Foo : I {
|
||||||
// no getter
|
// no getter
|
||||||
val a0: Int
|
val a0: Int
|
||||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val e0: Int<!>
|
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val e0: Int<!>
|
||||||
val c0: Int = 1
|
val c0: Int = 1
|
||||||
override val b0: Int
|
override val b0: Int
|
||||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>override val f0: Int<!>
|
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>override val f0: Int<!>
|
||||||
override val d0: Int = 1
|
override val d0: Int = 1
|
||||||
|
|
||||||
// getter with field
|
// getter with field
|
||||||
val a1: Int; get() = field
|
val a1: Int; get() = field
|
||||||
<!MUST_BE_INITIALIZED!>val e1: Int<!>; get() = field
|
<!MUST_BE_INITIALIZED!>val e1: Int<!>; get() = field
|
||||||
val c1: Int = 1; get() = field
|
val c1: Int = 1; get() = field
|
||||||
override val b1: Int; get() = field
|
override val b1: Int; get() = field
|
||||||
<!MUST_BE_INITIALIZED!>override val f1: Int<!>; get() = field
|
<!MUST_BE_INITIALIZED!>override val f1: Int<!>; get() = field
|
||||||
override val d1: Int = 1; get() = field
|
override val d1: Int = 1; get() = field
|
||||||
|
|
||||||
// getter with empty body
|
// getter with empty body
|
||||||
val a2: Int; get
|
val a2: Int; get
|
||||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val e2: Int<!>; get
|
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val e2: Int<!>; get
|
||||||
val c2: Int = 1; get
|
val c2: Int = 1; get
|
||||||
override val b2: Int; get
|
override val b2: Int; get
|
||||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>override val f2: Int<!>; get
|
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>override val f2: Int<!>; get
|
||||||
override val d2: Int = 1; get
|
override val d2: Int = 1; get
|
||||||
|
|
||||||
// getter no field
|
// getter no field
|
||||||
val a3: Int; get() = 1
|
val a3: Int; get() = 1
|
||||||
|
|||||||
-53
@@ -1,53 +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 getter
|
|
||||||
val a0: Int
|
|
||||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val e0: Int<!>
|
|
||||||
val c0: Int = 1
|
|
||||||
<!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
|
|
||||||
|
|
||||||
// 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_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
|
|
||||||
|
|
||||||
// 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_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
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-53
@@ -1,53 +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 getter
|
|
||||||
val a0: Int
|
|
||||||
<!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>val e0: Int<!>
|
|
||||||
val c0: Int = 1
|
|
||||||
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
|
|
||||||
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
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+55
@@ -0,0 +1,55 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// !DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS
|
||||||
|
// !LANGUAGE:+ProhibitOpenValDeferredInitialization
|
||||||
|
// 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_FINAL_OR_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_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
|
||||||
|
|
||||||
|
// 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_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
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+55
@@ -0,0 +1,55 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// !DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS
|
||||||
|
// !LANGUAGE:-ProhibitOpenValDeferredInitialization
|
||||||
|
// 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_FINAL_OR_ABSTRACT_WARNING!>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_OR_BE_FINAL_WARNING!>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_FINAL_OR_ABSTRACT_WARNING!>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
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+27
-3
@@ -2990,6 +2990,24 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt");
|
runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitSecondaryConstructorErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitSecondaryConstructorErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitSecondaryConstructorErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("OpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway.kt")
|
||||||
|
public void testOpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/OpenValPartialDeferredInitTwoSecondaryConstructorsErrorAnyway.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("SetterWithExplicitType.kt")
|
@TestMetadata("SetterWithExplicitType.kt")
|
||||||
public void testSetterWithExplicitType() throws Exception {
|
public void testSetterWithExplicitType() throws Exception {
|
||||||
@@ -3003,9 +3021,15 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("ValDeferredInitInOpenClass.kt")
|
@TestMetadata("ValDeferredInitInOpenClassOpenValError.kt")
|
||||||
public void testValDeferredInitInOpenClass() throws Exception {
|
public void testValDeferredInitInOpenClassOpenValError() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClass.kt");
|
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClassOpenValError.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("ValDeferredInitInOpenClassOpenValWarning.kt")
|
||||||
|
public void testValDeferredInitInOpenClassOpenValWarning() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/backingField/ValDeferredInitInOpenClassOpenValWarning.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -288,6 +288,7 @@ enum class LanguageFeature(
|
|||||||
ProhibitUseSiteGetTargetAnnotations(KOTLIN_2_0, kind = BUG_FIX), // KT-15470
|
ProhibitUseSiteGetTargetAnnotations(KOTLIN_2_0, kind = BUG_FIX), // KT-15470
|
||||||
KeepNullabilityWhenApproximatingLocalType(KOTLIN_2_0, kind = BUG_FIX), // KT-53982
|
KeepNullabilityWhenApproximatingLocalType(KOTLIN_2_0, kind = BUG_FIX), // KT-53982
|
||||||
ProhibitAccessToInvisibleSetterFromDerivedClass(KOTLIN_2_0, kind = BUG_FIX), // KT-56662
|
ProhibitAccessToInvisibleSetterFromDerivedClass(KOTLIN_2_0, kind = BUG_FIX), // KT-56662
|
||||||
|
ProhibitOpenValDeferredInitialization(KOTLIN_2_0, kind = BUG_FIX), // KT-57553
|
||||||
|
|
||||||
// 2.1
|
// 2.1
|
||||||
|
|
||||||
|
|||||||
+1
@@ -1,4 +1,5 @@
|
|||||||
// EXPECTED_REACHABLE_NODES: 1297
|
// EXPECTED_REACHABLE_NODES: 1297
|
||||||
|
// LANGUAGE: -ProhibitOpenValDeferredInitialization
|
||||||
// Test for KT-5673
|
// Test for KT-5673
|
||||||
|
|
||||||
package foo
|
package foo
|
||||||
|
|||||||
Reference in New Issue
Block a user