Use common instance receiver generation logic for 'this' expression
Otherwise it would skip private companion object accessor generation.
This commit is contained in:
@@ -2673,28 +2673,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
public StackValue generateReceiverValue(@Nullable ReceiverValue receiverValue, boolean isSuper) {
|
public StackValue generateReceiverValue(@Nullable ReceiverValue receiverValue, boolean isSuper) {
|
||||||
if (receiverValue instanceof ImplicitClassReceiver) {
|
if (receiverValue instanceof ImplicitClassReceiver) {
|
||||||
ClassDescriptor receiverDescriptor = ((ImplicitClassReceiver) receiverValue).getDeclarationDescriptor();
|
ClassDescriptor receiverDescriptor = ((ImplicitClassReceiver) receiverValue).getDeclarationDescriptor();
|
||||||
if (DescriptorUtils.isCompanionObject(receiverDescriptor)) {
|
return generateInstanceReceiver(receiverDescriptor, isSuper,
|
||||||
CallableMemberDescriptor contextDescriptor = context.getContextDescriptor();
|
receiverValue instanceof CastImplicitClassReceiver || isEnumEntry(receiverDescriptor));
|
||||||
if (contextDescriptor instanceof FunctionDescriptor && receiverDescriptor == contextDescriptor.getContainingDeclaration()) {
|
|
||||||
return StackValue.LOCAL_0;
|
|
||||||
}
|
|
||||||
else if (isPossiblyUninitializedSingleton(receiverDescriptor) && isInsideSingleton(receiverDescriptor)) {
|
|
||||||
return generateThisOrOuterFromContext(receiverDescriptor, false, false);
|
|
||||||
}
|
|
||||||
else if (couldUseDirectAccessToCompanionObject(receiverDescriptor, context)) {
|
|
||||||
return StackValue.singleton(receiverDescriptor, typeMapper);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return generateAccessorCallForCompanionObject(receiverDescriptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (receiverDescriptor instanceof ScriptDescriptor) {
|
|
||||||
return generateScriptReceiver((ScriptDescriptor) receiverDescriptor);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return StackValue.thisOrOuter(this, receiverDescriptor, isSuper,
|
|
||||||
receiverValue instanceof CastImplicitClassReceiver || isEnumEntry(receiverDescriptor));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (receiverValue instanceof ExtensionReceiver) {
|
else if (receiverValue instanceof ExtensionReceiver) {
|
||||||
return generateExtensionReceiver(((ExtensionReceiver) receiverValue).getDeclarationDescriptor());
|
return generateExtensionReceiver(((ExtensionReceiver) receiverValue).getDeclarationDescriptor());
|
||||||
@@ -2714,6 +2694,35 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private StackValue generateInstanceReceiver(
|
||||||
|
@NotNull ClassDescriptor receiverDescriptor,
|
||||||
|
boolean isSuper,
|
||||||
|
boolean castReceiver
|
||||||
|
|
||||||
|
) {
|
||||||
|
if (DescriptorUtils.isCompanionObject(receiverDescriptor)) {
|
||||||
|
CallableMemberDescriptor contextDescriptor = context.getContextDescriptor();
|
||||||
|
if (contextDescriptor instanceof FunctionDescriptor && receiverDescriptor == contextDescriptor.getContainingDeclaration()) {
|
||||||
|
return StackValue.LOCAL_0;
|
||||||
|
}
|
||||||
|
else if (isPossiblyUninitializedSingleton(receiverDescriptor) && isInsideSingleton(receiverDescriptor)) {
|
||||||
|
return generateThisOrOuterFromContext(receiverDescriptor, false, false);
|
||||||
|
}
|
||||||
|
else if (couldUseDirectAccessToCompanionObject(receiverDescriptor, context)) {
|
||||||
|
return StackValue.singleton(receiverDescriptor, typeMapper);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return generateAccessorCallForCompanionObject(receiverDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (receiverDescriptor instanceof ScriptDescriptor) {
|
||||||
|
return generateScriptReceiver((ScriptDescriptor) receiverDescriptor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return StackValue.thisOrOuter(this, receiverDescriptor, isSuper, castReceiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private StackValue generateAccessorCallForCompanionObject(@NotNull ClassDescriptor companionObjectDescriptor) {
|
private StackValue generateAccessorCallForCompanionObject(@NotNull ClassDescriptor companionObjectDescriptor) {
|
||||||
DeclarationDescriptor hostClassDescriptor = companionObjectDescriptor.getContainingDeclaration();
|
DeclarationDescriptor hostClassDescriptor = companionObjectDescriptor.getContainingDeclaration();
|
||||||
@@ -4408,8 +4417,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
public StackValue visitThisExpression(@NotNull KtThisExpression expression, StackValue receiver) {
|
public StackValue visitThisExpression(@NotNull KtThisExpression expression, StackValue receiver) {
|
||||||
DeclarationDescriptor descriptor = bindingContext.get(REFERENCE_TARGET, expression.getInstanceReference());
|
DeclarationDescriptor descriptor = bindingContext.get(REFERENCE_TARGET, expression.getInstanceReference());
|
||||||
if (descriptor instanceof ClassDescriptor) {
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
|
return generateInstanceReceiver((ClassDescriptor) descriptor, false, true);
|
||||||
//TODO rewrite with context.lookupInContext()
|
//TODO rewrite with context.lookupInContext()
|
||||||
return StackValue.thisOrOuter(this, (ClassDescriptor) descriptor, false, true);
|
//return StackValue.thisOrOuter(this, (ClassDescriptor) descriptor, false, true);
|
||||||
}
|
}
|
||||||
if (descriptor instanceof CallableDescriptor) {
|
if (descriptor instanceof CallableDescriptor) {
|
||||||
return generateExtensionReceiver((CallableDescriptor) descriptor);
|
return generateExtensionReceiver((CallableDescriptor) descriptor);
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
|
||||||
|
// IGNORE_BACKEND: JS, JS_IR, JVM_IR
|
||||||
|
|
||||||
|
inline fun on(body: () -> Any) = body().toString()
|
||||||
|
|
||||||
|
class A {
|
||||||
|
fun test() = foo()
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
private fun foo() = on { this }
|
||||||
|
|
||||||
|
override fun toString() = "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun box() = A().test()
|
||||||
+5
@@ -15118,6 +15118,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt27117.kt")
|
||||||
|
public void testKt27117() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt")
|
@TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt")
|
||||||
public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception {
|
public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt");
|
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt");
|
||||||
|
|||||||
+5
@@ -15118,6 +15118,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt27117.kt")
|
||||||
|
public void testKt27117() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt")
|
@TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt")
|
||||||
public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception {
|
public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt");
|
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt");
|
||||||
|
|||||||
+5
@@ -15123,6 +15123,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt27117.kt")
|
||||||
|
public void testKt27117() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt")
|
@TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt")
|
||||||
public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception {
|
public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt");
|
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt");
|
||||||
|
|||||||
+5
@@ -13303,6 +13303,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt27117.kt")
|
||||||
|
public void testKt27117() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt")
|
@TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt")
|
||||||
public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception {
|
public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt");
|
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt");
|
||||||
|
|||||||
+5
@@ -14348,6 +14348,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt27117.kt")
|
||||||
|
public void testKt27117() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt")
|
@TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt")
|
||||||
public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception {
|
public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt");
|
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user