diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 40d6e32897b..ebb23b3fc8a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -2784,7 +2784,7 @@ public class ExpressionCodegen extends KtVisitor impleme } @Nullable - private StackValue generateCallableReferenceReceiver(@NotNull ResolvedCall resolvedCall) { + public StackValue generateCallableReferenceReceiver(@NotNull ResolvedCall resolvedCall) { CallableDescriptor descriptor = resolvedCall.getResultingDescriptor(); if (descriptor.getExtensionReceiverParameter() == null && descriptor.getDispatchReceiverParameter() == null) return null; diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/LateinitIntrinsics.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/LateinitIntrinsics.kt index ce6015f2018..abba2ee6b76 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/LateinitIntrinsics.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/LateinitIntrinsics.kt @@ -36,9 +36,9 @@ object LateinitIsInitialized : IntrinsicPropertyGetter() { private fun getStackValue(resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): StackValue? { val expression = (resolvedCall.extensionReceiver as? ExpressionReceiver)?.expression as? KtCallableReferenceExpression ?: return null + val referenceResolvedCall = expression.callableReference.getResolvedCallWithAssert(codegen.bindingContext) - // TODO: support properties imported from objects as soon as KT-18982 is fixed - val receiver = expression.receiverExpression?.let(codegen::gen) ?: StackValue.none() + val receiver = codegen.generateCallableReferenceReceiver(referenceResolvedCall) ?: StackValue.none() val target = expression.callableReference.getResolvedCallWithAssert(codegen.bindingContext).resultingDescriptor return codegen.intermediateValueForProperty(target as PropertyDescriptor, true, false, null, false, receiver, null, true) diff --git a/compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/emptyLhs.kt b/compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/emptyLhs.kt new file mode 100644 index 00000000000..ba00a415ddb --- /dev/null +++ b/compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/emptyLhs.kt @@ -0,0 +1,50 @@ +// WITH_RUNTIME + +package test + +import kotlin.reflect.KProperty +import test.Derived.p + +class Foo { + lateinit var p: String + + fun test(): Boolean { + if (!::p.isInitialized) { + p = "OK" + return false + } + return true + } +} + +object Bar { + lateinit var p: String + + fun test(): Boolean { + if (!::p.isInitialized) { + p = "OK" + return false + } + return true + } +} + +open class Base(val b: Boolean) + +object Derived : Base(::p.isInitialized) { + lateinit var p: String +} + +fun box(): String { + val foo = Foo() + if (foo.test()) return "Fail 1" + if (!foo.test()) return "Fail 2" + + val bar = Bar + if (bar.test()) return "Fail 3" + if (!bar.test()) return "Fail 4" + + if (Derived.b) return "Fail 5" + + return bar.p +} diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index ab19693dc42..a49e6a25702 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -13908,6 +13908,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("emptyLhs.kt") + public void testEmptyLhs() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/emptyLhs.kt"); + doTest(fileName); + } + @TestMetadata("innerSubclass.kt") public void testInnerSubclass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 5e1f9130467..ff3aba544da 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -13908,6 +13908,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("emptyLhs.kt") + public void testEmptyLhs() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/emptyLhs.kt"); + doTest(fileName); + } + @TestMetadata("innerSubclass.kt") public void testInnerSubclass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 7a76830b088..5a304495658 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -13908,6 +13908,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("emptyLhs.kt") + public void testEmptyLhs() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/emptyLhs.kt"); + doTest(fileName); + } + @TestMetadata("innerSubclass.kt") public void testInnerSubclass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index df0e1eeff72..7539523a6b7 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -15240,6 +15240,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); } + @TestMetadata("emptyLhs.kt") + public void testEmptyLhs() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/emptyLhs.kt"); + doTest(fileName); + } + @TestMetadata("innerSubclass.kt") public void testInnerSubclass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt");