From ccfbb5f77a68b436f9889575e8ed504c3390a8b7 Mon Sep 17 00:00:00 2001 From: Nikita Bobko Date: Fri, 18 Aug 2023 14:44:09 +0200 Subject: [PATCH] [FE] Don't issue a deprecation warning for open val deferred init when the property is unconditionally effectively final ^KT-61228 Fixed Review: https://jetbrains.team/p/kt/reviews/11694/timeline --- ...CompilerTestFE10TestdataTestGenerated.java | 24 ++++++++++ ...sticCompilerFE10TestDataTestGenerated.java | 24 ++++++++++ ...eeOldFrontendDiagnosticsTestGenerated.java | 24 ++++++++++ ...siOldFrontendDiagnosticsTestGenerated.java | 24 ++++++++++ .../FirTopLevelPropertiesChecker.kt | 36 +++++++++++---- .../kotlin/resolve/DeclarationsChecker.kt | 45 ++++++++++++------- ...or_InFinalClass_DisableEffectivelyFinal.kt | 29 ++++++++++++ ...ror_InFinalClass_EnableEffectivelyFinal.kt | 15 +++++++ ...ng_InFinalClass_DisableEffectivelyFinal.kt | 16 +++++++ ...ing_InFinalClass_EnableEffectivelyFinal.kt | 15 +++++++ .../test/runners/DiagnosticTestGenerated.java | 24 ++++++++++ 11 files changed, 250 insertions(+), 26 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal.kt create mode 100644 compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal.kt create mode 100644 compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal.kt create mode 100644 compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index 162ee1235f0..9347826c1e9 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -3134,6 +3134,30 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt"); } + @Test + @TestMetadata("OpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal.kt") + public void testOpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal.kt") + public void testOpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal.kt") + public void testOpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal.kt") + public void testOpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal.kt"); + } + @Test @TestMetadata("OpenValPartialDeferredInitErrorAnyway.kt") public void testOpenValPartialDeferredInitErrorAnyway() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index bbe2f487a89..36c28c14737 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -3134,6 +3134,30 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt"); } + @Test + @TestMetadata("OpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal.kt") + public void testOpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal.kt") + public void testOpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal.kt") + public void testOpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal.kt") + public void testOpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal.kt"); + } + @Test @TestMetadata("OpenValPartialDeferredInitErrorAnyway.kt") public void testOpenValPartialDeferredInitErrorAnyway() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index a19abebcedb..7ed1dbfedc6 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -3134,6 +3134,30 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt"); } + @Test + @TestMetadata("OpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal.kt") + public void testOpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal.kt") + public void testOpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal.kt") + public void testOpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal.kt") + public void testOpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal.kt"); + } + @Test @TestMetadata("OpenValPartialDeferredInitErrorAnyway.kt") public void testOpenValPartialDeferredInitErrorAnyway() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index df32c4aff29..c31050bf5f7 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -3140,6 +3140,30 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt"); } + @Test + @TestMetadata("OpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal.kt") + public void testOpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal.kt") + public void testOpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal.kt") + public void testOpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal.kt") + public void testOpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal.kt"); + } + @Test @TestMetadata("OpenValPartialDeferredInitErrorAnyway.kt") public void testOpenValPartialDeferredInitErrorAnyway() throws Exception { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelPropertiesChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelPropertiesChecker.kt index 08b375c74c9..9c72dcfb72c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelPropertiesChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirTopLevelPropertiesChecker.kt @@ -10,7 +10,6 @@ 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.KtDiagnosticFactory0 import org.jetbrains.kotlin.diagnostics.reportOn @@ -133,7 +132,24 @@ internal fun checkPropertyInitializer( if (property.receiverParameter != null && !property.hasAllAccessorImplementation) { reporter.reportOn(propertySource, FirErrors.EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT, context) } else if (reachable) { - reportMustBeInitialized(property, isDefinitelyAssignedInConstructor, containingClass, propertySource, reporter, context) + val isOpenValDeferredInitDeprecationWarning = + !context.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitOpenValDeferredInitialization) && + property.getEffectiveModality(containingClass, context.languageVersionSettings) == Modality.OPEN && property.isVal && + isDefinitelyAssignedInConstructor + // KT-61228 + val isFalsePositiveDeferredInitDeprecationWarning = isOpenValDeferredInitDeprecationWarning && + property.getEffectiveModality(containingClass) == Modality.FINAL + if (!isFalsePositiveDeferredInitDeprecationWarning) { + reportMustBeInitialized( + property, + isDefinitelyAssignedInConstructor, + containingClass, + propertySource, + isOpenValDeferredInitDeprecationWarning, + reporter, + context + ) + } } } if (property.isLateInit) { @@ -156,6 +172,7 @@ private fun reportMustBeInitialized( isDefinitelyAssignedInConstructor: Boolean, containingClass: FirClass?, propertySource: KtSourceElement, + isOpenValDeferredInitDeprecationWarning: Boolean, reporter: DiagnosticReporter, context: CheckerContext, ) { @@ -165,10 +182,6 @@ private fun reportMustBeInitialized( property.getEffectiveModality(containingClass, context.languageVersionSettings) != Modality.FINAL && isDefinitelyAssignedInConstructor val suggestMakingItAbstract = containingClass != null && !property.hasAnyAccessorImplementation - val isOpenValDeferredInitDeprecationWarning = - !context.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitOpenValDeferredInitialization) && - property.getEffectiveModality(containingClass, context.languageVersionSettings) == Modality.OPEN && property.isVal && - isDefinitelyAssignedInConstructor if (isOpenValDeferredInitDeprecationWarning && !suggestMakingItFinal && suggestMakingItAbstract) { error("Not reachable case. Every \"open val + deferred init\" case that could be made `abstract`, also could be made `final`") } @@ -212,9 +225,14 @@ private val FirProperty.hasAnyAccessorImplementation: Boolean private val FirProperty.hasAllAccessorImplementation: Boolean get() = getter.hasImplementation && (isVal || 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) { +private fun FirProperty.getEffectiveModality(containingClass: FirClass?): Modality? = + when (status.modality == Modality.OPEN && containingClass?.status?.modality == Modality.FINAL) { true -> Modality.FINAL false -> status.modality } + +private fun FirProperty.getEffectiveModality(containingClass: FirClass?, languageVersionSettings: LanguageVersionSettings): Modality? = + when (languageVersionSettings.supportsFeature(LanguageFeature.TakeIntoAccountEffectivelyFinalInMustBeInitializedCheck)) { + true -> getEffectiveModality(containingClass) + false -> status.modality + } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt index 5f5abdeecfa..85620158e06 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.kt @@ -38,7 +38,6 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveOpenMembers import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns -import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotationConstructor import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal import org.jetbrains.kotlin.resolve.inline.isInlineOnly import org.jetbrains.kotlin.resolve.source.KotlinSourceElement @@ -796,14 +795,25 @@ class DeclarationsChecker( if (propertyDescriptor.extensionReceiverParameter != null && !hasAnyAccessorImplementation) { trace.report(EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT.on(property)) } else if (diagnosticSuppressor.shouldReportNoBody(propertyDescriptor)) { - reportMustBeInitialized( - propertyDescriptor, - containingDeclaration, - hasAnyAccessorImplementation, - property, - languageVersionSettings, - trace - ) + val isOpenValDeferredInitDeprecationWarning = + !languageVersionSettings.supportsFeature(LanguageFeature.ProhibitOpenValDeferredInitialization) && + propertyDescriptor.getEffectiveModality(languageVersionSettings) == Modality.OPEN && + !propertyDescriptor.isVar && + trace.bindingContext.get(IS_DEFINITELY_NOT_ASSIGNED_IN_CONSTRUCTOR, propertyDescriptor) == false + // KT-61228 + val isFalsePositiveDeferredInitDeprecationWarning = isOpenValDeferredInitDeprecationWarning && + propertyDescriptor.getEffectiveModality() == Modality.FINAL + if (!isFalsePositiveDeferredInitDeprecationWarning) { + reportMustBeInitialized( + propertyDescriptor, + containingDeclaration, + hasAnyAccessorImplementation, + property, + isOpenValDeferredInitDeprecationWarning, + languageVersionSettings, + trace + ) + } } } else if (property.typeReference == null && !languageVersionSettings.supportsFeature(LanguageFeature.ShortSyntaxForPropertyGetters)) { trace.report( @@ -832,6 +842,7 @@ class DeclarationsChecker( containingDeclaration: DeclarationDescriptor, hasAnyAccessorImplementation: Boolean, property: KtProperty, + isOpenValDeferredInitDeprecationWarning: Boolean, languageVersionSettings: LanguageVersionSettings, trace: BindingTrace, ) { @@ -843,11 +854,6 @@ class DeclarationsChecker( propertyDescriptor.getEffectiveModality(languageVersionSettings) != Modality.FINAL && trace.bindingContext.get(IS_DEFINITELY_NOT_ASSIGNED_IN_CONSTRUCTOR, propertyDescriptor) == false 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 if (isOpenValDeferredInitDeprecationWarning && !suggestMakingItFinal && suggestMakingItAbstract) { error("Not reachable case. Every \"open val + deferred init\" case that could be made `abstract`, also could be made `final`") } @@ -1132,9 +1138,14 @@ class DeclarationsChecker( } } -fun PropertyDescriptor.getEffectiveModality(languageVersionSettings: LanguageVersionSettings): Modality = - when (languageVersionSettings.supportsFeature(LanguageFeature.TakeIntoAccountEffectivelyFinalInMustBeInitializedCheck) && - modality == Modality.OPEN && (containingDeclaration as? ClassDescriptor)?.modality == Modality.FINAL) { +private fun PropertyDescriptor.getEffectiveModality(): Modality = + when (modality == Modality.OPEN && (containingDeclaration as? ClassDescriptor)?.modality == Modality.FINAL) { true -> Modality.FINAL false -> modality } + +fun PropertyDescriptor.getEffectiveModality(languageVersionSettings: LanguageVersionSettings): Modality = + when (languageVersionSettings.supportsFeature(LanguageFeature.TakeIntoAccountEffectivelyFinalInMustBeInitializedCheck)) { + true -> getEffectiveModality() + false -> modality + } diff --git a/compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal.kt b/compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal.kt new file mode 100644 index 00000000000..f35ff8fc4e2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal.kt @@ -0,0 +1,29 @@ +// FIR_IDENTICAL +// DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS +// LANGUAGE:-TakeIntoAccountEffectivelyFinalInMustBeInitializedCheck +// LANGUAGE:+ProhibitOpenValDeferredInitialization + +// Invalid combination of language feature flags. The user enabled 2.0 language flag (+ProhibitOpenValDeferredInitialization) and disabled +// 1.9 language flag (-TakeIntoAccountEffectivelyFinalInMustBeInitializedCheck) => It's only possible if users manually set `-XXLanguage` => +// Technically, it's UB (undefined behaviour) +// +// On one hand, suppose that you have 1.9.0 compiler with -XXLanguage:-TakeIntoAccountEffectivelyFinalInMustBeInitializedCheck and then you +// bump your compiler version to 1.9.20. It's not nice that you will get this compilation error considering that you didn't have a warning +// => so probably we shouldn't report a error here +// +// But on the other hand, the error is expected by the combination of feature flags (we prohibit open val deferred initialization and +// since we don't take effectively final into account) => we must be report a error +// +// Anyway, it's UB. Users shouldn't manually tune `-XXLanguage` + +interface Base { + val foo: Int +} + +class Foo : Base { + override val foo: Int + + init { + foo = 1 + } +} diff --git a/compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal.kt b/compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal.kt new file mode 100644 index 00000000000..c53bb89dcd2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal.kt @@ -0,0 +1,15 @@ +// FIR_IDENTICAL +// DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS +// LANGUAGE:+TakeIntoAccountEffectivelyFinalInMustBeInitializedCheck +// LANGUAGE:+ProhibitOpenValDeferredInitialization +interface Base { + val foo: Int +} + +class Foo : Base { + override val foo: Int + + init { + foo = 1 + } +} diff --git a/compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal.kt b/compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal.kt new file mode 100644 index 00000000000..2dbcb2d031a --- /dev/null +++ b/compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal.kt @@ -0,0 +1,16 @@ +// FIR_IDENTICAL +// DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS +// LANGUAGE:-TakeIntoAccountEffectivelyFinalInMustBeInitializedCheck +// LANGUAGE:-ProhibitOpenValDeferredInitialization +// KT-61228 case +interface Base { + val foo: Int +} + +class Foo : Base { + override val foo: Int + + init { + foo = 1 + } +} diff --git a/compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal.kt b/compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal.kt new file mode 100644 index 00000000000..5f112eef8d0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal.kt @@ -0,0 +1,15 @@ +// FIR_IDENTICAL +// DIAGNOSTICS: -DEBUG_INFO_LEAKING_THIS +// LANGUAGE:+TakeIntoAccountEffectivelyFinalInMustBeInitializedCheck +// LANGUAGE:-ProhibitOpenValDeferredInitialization +interface Base { + val foo: Int +} + +class Foo : Base { + override val foo: Int + + init { + foo = 1 + } +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 6103642df06..c451f0ef756 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -3140,6 +3140,30 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/backingField/MustBeInitializedEffectivelyFinalOn.kt"); } + @Test + @TestMetadata("OpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal.kt") + public void testOpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_DisableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal.kt") + public void testOpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitError_InFinalClass_EnableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal.kt") + public void testOpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_DisableEffectivelyFinal.kt"); + } + + @Test + @TestMetadata("OpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal.kt") + public void testOpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal() throws Exception { + runTest("compiler/testData/diagnostics/tests/backingField/OpenValDeferredInitWarning_InFinalClass_EnableEffectivelyFinal.kt"); + } + @Test @TestMetadata("OpenValPartialDeferredInitErrorAnyway.kt") public void testOpenValPartialDeferredInitErrorAnyway() throws Exception {