diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt index cab0a3a56f4..255dbe5533b 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/IrUtils.kt @@ -197,6 +197,7 @@ val IrProperty.isSimpleProperty: Boolean val getterFun = getter val setterFun = setter return !isFakeOverride && + !isLateinit && modality === Modality.FINAL && (getterFun == null || getterFun.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) && (setterFun == null || setterFun.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java index 1828c99127e..b1a611b5d06 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java @@ -2100,6 +2100,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/box/export"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.JS, true); } + @Test + @TestMetadata("consumeExportedLateinitProperty.kt") + public void testConsumeExportedLateinitProperty() throws Exception { + runTest("js/js.translator/testData/box/export/consumeExportedLateinitProperty.kt"); + } + @Test @TestMetadata("defaultInlineClassConstructorParam.kt") public void testDefaultInlineClassConstructorParam() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/FirJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/FirJsTestGenerated.java index 6c7998246a8..a855a1d34ce 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/FirJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/FirJsTestGenerated.java @@ -2572,6 +2572,12 @@ public class FirJsTestGenerated extends AbstractFirJsTest { runTest("js/js.translator/testData/box/export/bridgeSavingAfterExportInExportedFile.kt"); } + @Test + @TestMetadata("consumeExportedLateinitProperty.kt") + public void testConsumeExportedLateinitProperty() throws Exception { + runTest("js/js.translator/testData/box/export/consumeExportedLateinitProperty.kt"); + } + @Test @TestMetadata("defaultInlineClassConstructorParam.kt") public void testDefaultInlineClassConstructorParam() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java index 1f9efe60d74..8c161621938 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java @@ -2572,6 +2572,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { runTest("js/js.translator/testData/box/export/bridgeSavingAfterExportInExportedFile.kt"); } + @Test + @TestMetadata("consumeExportedLateinitProperty.kt") + public void testConsumeExportedLateinitProperty() throws Exception { + runTest("js/js.translator/testData/box/export/consumeExportedLateinitProperty.kt"); + } + @Test @TestMetadata("defaultInlineClassConstructorParam.kt") public void testDefaultInlineClassConstructorParam() throws Exception { diff --git a/js/js.translator/testData/box/export/consumeExportedLateinitProperty.kt b/js/js.translator/testData/box/export/consumeExportedLateinitProperty.kt new file mode 100644 index 00000000000..71b25a380b7 --- /dev/null +++ b/js/js.translator/testData/box/export/consumeExportedLateinitProperty.kt @@ -0,0 +1,19 @@ +// KT-53968 +// EXPECTED_REACHABLE_NODES: 1252 + +@JsExport +class LateinitContainer { + lateinit var value: String; +} + +fun box(): String { + val container = LateinitContainer() + try { + container.value + return "Fail: problem with lateinit getter." + } catch (e: Exception) {} + + container.value = "Test" + assertEquals(container.value, "Test") + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/box/export/exportClassPropertiesInDifferentCombinations.kt b/js/js.translator/testData/box/export/exportClassPropertiesInDifferentCombinations.kt index df340cf5198..32f6ee292f4 100644 --- a/js/js.translator/testData/box/export/exportClassPropertiesInDifferentCombinations.kt +++ b/js/js.translator/testData/box/export/exportClassPropertiesInDifferentCombinations.kt @@ -20,6 +20,9 @@ interface IOwner { open class Owner { open val classOpenReadonly: String = "Class Readonly Open" open var classOpenVar: String = "Class Var Open" + open lateinit var classOpenLateinitVar: String; + + lateinit var classLateinitVar: String; val classFinalReadonly: String = "Class Readonly Final" var classFinalVar: String = "Class Default" @@ -63,6 +66,7 @@ open class AnotherOneHiddenChild: HiddenChild() { class ExportedChild: AnotherOneHiddenChild() { override val classOpenReadonly: String = "Exported Child Readonly Open" override var classOpenVar: String = "Exported Child Var Open" + override var classOpenLateinitVar: String = "Exported Child Lateinit Open Var" override val classOpenGetterOnly: String get() = "Exported Child with Open Getter" @@ -95,6 +99,22 @@ function testOwner(pkg) { assertEquals(owner.classOpenReadonly, "Class Readonly Open") assertEquals(owner.classOpenVar, "Class Var Open") + try { + owner.classOpenLateinitVar; + return "Fail: invalid getter for open lateinit var in Owner class"; + } catch(e) {} + + owner.classOpenLateinitVar = "Class Open Lateinit Var" + assertEquals(owner.classOpenLateinitVar, "Class Open Lateinit Var") + + try { + owner.classLateinitVar; + return "Fail: invalid getter for lateinit var in Owner class"; + } catch(e) {} + + owner.classLateinitVar = "Class Lateinit Var" + assertEquals(owner.classLateinitVar, "Class Lateinit Var") + assertEquals(owner.classFinalReadonly, "Class Readonly Final") assertEquals(owner.classFinalVar, "Class Default") @@ -130,6 +150,22 @@ function testHiddenChild(pkg) { assertEquals(owner.classOpenReadonly, "Class Readonly Open") assertEquals(owner.classOpenVar, "Class Var Open") + try { + owner.classOpenLateinitVar; + return "Fail: invalid getter for open lateinit var in Hidden Child class"; + } catch(e) {} + + owner.classOpenLateinitVar = "Hidden Child Open Lateinit Var" + assertEquals(owner.classOpenLateinitVar, "Hidden Child Open Lateinit Var") + + try { + owner.classLateinitVar; + return "Fail: invalid getter for lateinit var in Hidden Child class"; + } catch(e) {} + + owner.classLateinitVar = "Hidden Child Lateinit Var" + assertEquals(owner.classLateinitVar, "Hidden Child Lateinit Var") + assertEquals(owner.classFinalReadonly, "Class Readonly Final") assertEquals(owner.classFinalVar, "Class Default") @@ -165,6 +201,22 @@ function testAnotherHiddenChild(pkg) { assertEquals(owner.classOpenReadonly, "Class Readonly Open") assertEquals(owner.classOpenVar, "Class Var Open") + try { + owner.classOpenLateinitVar; + return "Fail: invalid getter for open lateinit var in Another Hidden Child class"; + } catch(e) {} + + owner.classOpenLateinitVar = "Another Hidden Child Open Lateinit Var" + assertEquals(owner.classOpenLateinitVar, "Another Hidden Child Open Lateinit Var") + + try { + owner.classLateinitVar; + return "Fail: invalid getter for lateinit var in Another Hidden Child class"; + } catch(e) {} + + owner.classLateinitVar = "Another Hidden Child Lateinit Var" + assertEquals(owner.classLateinitVar, "Another Hidden Child Lateinit Var") + assertEquals(owner.classFinalReadonly, "Class Readonly Final") assertEquals(owner.classFinalVar, "Class Default") @@ -196,6 +248,24 @@ function testExportedChild(pkg) { assertEquals(owner.classOpenReadonly, "Exported Child Readonly Open") assertEquals(owner.classOpenVar, "Exported Child Var Open") + try { + owner.classOpenLateinitVar; + } catch(e) { + return "Fail: invalid overridding of getter for open lateinit var in ExportedChild class"; + } + + owner.classOpenLateinitVar = "Exported Child Open Lateinit Var" + assertEquals(owner.classOpenLateinitVar, "Exported Child Open Lateinit Var") + + try { + owner.classLateinitVar; + } catch(e) { + return "Fail: invalid overridding of getter for lateinit var in ExportedChild class"; + } + + owner.classLateinitVar = "Exported Child Lateinit Var" + assertEquals(owner.classLateinitVar, "Exported Child Lateinit Var") + assertEquals(owner.classFinalReadonly, "Class Readonly Final") assertEquals(owner.classFinalVar, "Class Default")