Fix isInitialized receiver generation for empty LHS
#KT-20774 Fixed
This commit is contained in:
@@ -2784,7 +2784,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private StackValue generateCallableReferenceReceiver(@NotNull ResolvedCall<?> resolvedCall) {
|
public StackValue generateCallableReferenceReceiver(@NotNull ResolvedCall<?> resolvedCall) {
|
||||||
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
|
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
|
||||||
if (descriptor.getExtensionReceiverParameter() == null && descriptor.getDispatchReceiverParameter() == null) return null;
|
if (descriptor.getExtensionReceiverParameter() == null && descriptor.getDispatchReceiverParameter() == null) return null;
|
||||||
|
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ object LateinitIsInitialized : IntrinsicPropertyGetter() {
|
|||||||
private fun getStackValue(resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): StackValue? {
|
private fun getStackValue(resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): StackValue? {
|
||||||
val expression =
|
val expression =
|
||||||
(resolvedCall.extensionReceiver as? ExpressionReceiver)?.expression as? KtCallableReferenceExpression ?: return null
|
(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 = codegen.generateCallableReferenceReceiver(referenceResolvedCall) ?: StackValue.none()
|
||||||
val receiver = expression.receiverExpression?.let(codegen::gen) ?: StackValue.none()
|
|
||||||
|
|
||||||
val target = expression.callableReference.getResolvedCallWithAssert(codegen.bindingContext).resultingDescriptor
|
val target = expression.callableReference.getResolvedCallWithAssert(codegen.bindingContext).resultingDescriptor
|
||||||
return codegen.intermediateValueForProperty(target as PropertyDescriptor, true, false, null, false, receiver, null, true)
|
return codegen.intermediateValueForProperty(target as PropertyDescriptor, true, false, null, false, receiver, null, true)
|
||||||
|
|||||||
+50
@@ -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
|
||||||
|
}
|
||||||
+6
@@ -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);
|
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")
|
@TestMetadata("innerSubclass.kt")
|
||||||
public void testInnerSubclass() throws Exception {
|
public void testInnerSubclass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt");
|
||||||
|
|||||||
@@ -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);
|
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")
|
@TestMetadata("innerSubclass.kt")
|
||||||
public void testInnerSubclass() throws Exception {
|
public void testInnerSubclass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt");
|
||||||
|
|||||||
@@ -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);
|
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")
|
@TestMetadata("innerSubclass.kt")
|
||||||
public void testInnerSubclass() throws Exception {
|
public void testInnerSubclass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt");
|
||||||
|
|||||||
@@ -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);
|
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")
|
@TestMetadata("innerSubclass.kt")
|
||||||
public void testInnerSubclass() throws Exception {
|
public void testInnerSubclass() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/lateinit/isInitializedAndDeinitialize/innerSubclass.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user