diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForCompanionObjectInstanceFieldDescriptor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForCompanionObjectInstanceFieldDescriptor.kt new file mode 100644 index 00000000000..a40c9768cb6 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AccessorForCompanionObjectInstanceFieldDescriptor.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.codegen + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl +import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl +import org.jetbrains.kotlin.name.Name + +class AccessorForCompanionObjectInstanceFieldDescriptor( + val companionObjectDescriptor: ClassDescriptor, + name: Name +) : + SimpleFunctionDescriptorImpl( + companionObjectDescriptor.containingDeclaration, + null, Annotations.EMPTY, + name, + CallableMemberDescriptor.Kind.DECLARATION, SourceElement.NO_SOURCE + ) { + + init { + initialize( + null, null, emptyList(), emptyList(), + companionObjectDescriptor.defaultType, + Modality.FINAL, + Visibilities.LOCAL + ) + } + + override fun createSubstitutedCopy( + newOwner: DeclarationDescriptor, + original: FunctionDescriptor?, + kind: CallableMemberDescriptor.Kind, + newName: Name?, + annotations: Annotations, + source: SourceElement + ): FunctionDescriptorImpl { + throw UnsupportedOperationException("Accessor for companion object $companionObjectDescriptor should not be substituted") + } +} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index 93d17e6d461..e65e7dce0c0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -400,6 +400,10 @@ public class AsmUtil { return NO_FLAG_PACKAGE_PRIVATE; } + if (memberDescriptor instanceof AccessorForCompanionObjectInstanceFieldDescriptor) { + return NO_FLAG_PACKAGE_PRIVATE; + } + // the following code is only for PRIVATE visibility of member if (memberDescriptor instanceof ConstructorDescriptor) { if (isEnumEntry(containingDeclaration)) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 7270870abed..9db30476638 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -1756,6 +1756,9 @@ public class ExpressionCodegen extends KtVisitor impleme if (shouldGenerateSingletonAsThisOrOuterFromContext(classDescriptor)) { return generateThisOrOuterFromContext(classDescriptor, false, false); } + if (isCompanionObject(classDescriptor) && !couldUseDirectAccessToCompanionObject(classDescriptor, context)) { + return generateAccessorCallForCompanionObject(classDescriptor); + } if (isObject(classDescriptor)) { return StackValue.singleton(classDescriptor, typeMapper); } @@ -2612,9 +2615,12 @@ public class ExpressionCodegen extends KtVisitor impleme else if (isPossiblyUninitializedSingleton(receiverDescriptor) && isInsideSingleton(receiverDescriptor)) { return generateThisOrOuterFromContext(receiverDescriptor, false, false); } - else { + else if (couldUseDirectAccessToCompanionObject(receiverDescriptor, context)) { return StackValue.singleton(receiverDescriptor, typeMapper); } + else { + return generateAccessorCallForCompanionObject(receiverDescriptor); + } } else if (receiverDescriptor instanceof ScriptDescriptor) { return generateScriptReceiver((ScriptDescriptor) receiverDescriptor); @@ -2642,6 +2648,41 @@ public class ExpressionCodegen extends KtVisitor impleme } } + @NotNull + private StackValue generateAccessorCallForCompanionObject(@NotNull ClassDescriptor companionObjectDescriptor) { + DeclarationDescriptor hostClassDescriptor = companionObjectDescriptor.getContainingDeclaration(); + assert hostClassDescriptor instanceof ClassDescriptor : + "Containing declaration of the companion object " + companionObjectDescriptor + + ": expected a class, actual: " + hostClassDescriptor; + + CodegenContext hostClassContext = context; + while (hostClassContext.getContextDescriptor() != hostClassDescriptor) { + hostClassContext = hostClassContext.getParentContext(); + assert hostClassContext != null : + "Host class context for " + hostClassDescriptor + " not found in context hierarchy for " + context; + } + + hostClassContext.markCompanionObjectDescriptorWithAccessorRequired(companionObjectDescriptor); + + Type hostClassType = typeMapper.mapClass((ClassifierDescriptor) hostClassDescriptor); + Type companionObjectType = typeMapper.mapClass(companionObjectDescriptor); + + // TODO given that we actually have corresponding AccessorForCompanionObjectInstanceFieldDescriptor, + // it might be a better idea to use general method call generation + return StackValue.operation( + companionObjectType, + companionObjectDescriptor.getDefaultType(), + v -> { + v.invokestatic( + hostClassType.getInternalName(), + getCompanionObjectAccessorName(companionObjectDescriptor), + Type.getMethodDescriptor(companionObjectType), + /* itf */ false + ); + return null; + }); + } + @NotNull private StackValue generateExtensionReceiver(@NotNull CallableDescriptor descriptor) { ReceiverParameterDescriptor parameter = descriptor.getExtensionReceiverParameter(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java index 0c92a38bfd7..1524d434783 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java @@ -22,9 +22,6 @@ import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor; import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor; -import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass; -import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass; -import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement; import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityUtilsKt; import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping; import org.jetbrains.kotlin.psi.Call; @@ -153,6 +150,29 @@ public class JvmCodegenUtil { return propertyDescriptor.isConst() || hasJvmFieldAnnotation(propertyDescriptor); } + public static boolean couldUseDirectAccessToCompanionObject( + @NotNull ClassDescriptor companionObjectDescriptor, + @NotNull MethodContext contextBeforeInline + ) { + if (!Visibilities.isPrivate(companionObjectDescriptor.getVisibility())) { + // Non-private companion object can be directly accessed anywhere it's allowed by the front-end. + return true; + } + + CodegenContext context = contextBeforeInline.getFirstCrossInlineOrNonInlineContext(); + if (context.isInlineMethodContext()) { + // Inline method can be called from a nested class. + return false; + } + + // Private companion object is directly accessible only from the corresponding class + return context.getContextDescriptor().getContainingDeclaration() == companionObjectDescriptor.getContainingDeclaration(); + } + + public static String getCompanionObjectAccessorName(@NotNull ClassDescriptor companionObjectDescriptor) { + return "access$" + companionObjectDescriptor.getName(); + } + public static boolean couldUseDirectAccessToProperty( @NotNull PropertyDescriptor property, boolean forGetter, diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 92b3041f1b6..92e8c387338 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -708,6 +708,30 @@ public abstract class MemberCodegen accessorForCallableDescriptor) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java index e9eeccfd476..f5b0a36c0d6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.load.java.JavaVisibilities; import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor; +import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.storage.LockBasedStorageManager; @@ -44,12 +45,12 @@ public abstract class CodegenContext { private Map childContexts; private Map> accessors; private Map propertyAccessorFactories; + private AccessorForCompanionObjectInstanceFieldDescriptor accessorForCompanionObjectInstanceFieldDescriptor = null; private static class AccessorKey { public final DeclarationDescriptor descriptor; public final ClassDescriptor superCallLabelTarget; public final AccessorKind accessorKind; - public AccessorKey( @NotNull DeclarationDescriptor descriptor, @Nullable ClassDescriptor superCallLabelTarget, @@ -742,4 +743,30 @@ public abstract class CodegenContext { public LocalLookup getEnclosingLocalLookup() { return enclosingLocalLookup; } + + @NotNull + public AccessorForCompanionObjectInstanceFieldDescriptor markCompanionObjectDescriptorWithAccessorRequired(@NotNull ClassDescriptor companionObjectDescriptor) { + assert DescriptorUtils.isCompanionObject(companionObjectDescriptor) : "Companion object expected: " + companionObjectDescriptor; + + assert accessorForCompanionObjectInstanceFieldDescriptor == null + || accessorForCompanionObjectInstanceFieldDescriptor.getCompanionObjectDescriptor() == companionObjectDescriptor + : "Unexpected companion object descriptor with accessor required: " + companionObjectDescriptor + + "; should be " + accessorForCompanionObjectInstanceFieldDescriptor.getCompanionObjectDescriptor(); + + if (accessorForCompanionObjectInstanceFieldDescriptor == null) { + accessorForCompanionObjectInstanceFieldDescriptor = + new AccessorForCompanionObjectInstanceFieldDescriptor( + companionObjectDescriptor, + Name.identifier(JvmCodegenUtil.getCompanionObjectAccessorName(companionObjectDescriptor)) + ); + } + + return accessorForCompanionObjectInstanceFieldDescriptor; + } + + @Nullable + public AccessorForCompanionObjectInstanceFieldDescriptor getAccessorForCompanionObjectDescriptorIfRequired() { + return accessorForCompanionObjectInstanceFieldDescriptor; + } + } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java index 3569aa72436..d6f7d91d965 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java @@ -948,7 +948,8 @@ public class KotlinTypeMapper { } public static boolean isAccessor(@Nullable CallableMemberDescriptor descriptor) { - return descriptor instanceof AccessorForCallableDescriptor; + return descriptor instanceof AccessorForCallableDescriptor || + descriptor instanceof AccessorForCompanionObjectInstanceFieldDescriptor; } public static boolean isStaticAccessor(@Nullable CallableMemberDescriptor descriptor) { diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/JvmDeclarationOrigin.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/JvmDeclarationOrigin.kt index 9c4c5ffe378..f1f1e2876bc 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/JvmDeclarationOrigin.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/JvmDeclarationOrigin.kt @@ -84,7 +84,7 @@ fun Delegation(element: PsiElement?, descriptor: FunctionDescriptor): JvmDeclara fun SamDelegation(descriptor: FunctionDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(SAM_DELEGATION, null, descriptor) -fun Synthetic(element: PsiElement?, descriptor: CallableMemberDescriptor): JvmDeclarationOrigin = +fun Synthetic(element: PsiElement?, descriptor: DeclarationDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(SYNTHETIC, element, descriptor) val CollectionStub = JvmDeclarationOrigin(COLLECTION_STUB, null, null) diff --git a/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt b/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt new file mode 100644 index 00000000000..0841ff513e0 --- /dev/null +++ b/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt @@ -0,0 +1,17 @@ +// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField + +class Outer { + private companion object { + val result = "OK" + } + + class Nested { + fun foo() = object { + override fun toString(): String = result + } + } + + fun test() = Nested().foo().toString() +} + +fun box() = Outer().test() \ No newline at end of file diff --git a/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromInlineLambdaInNestedClass.kt b/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromInlineLambdaInNestedClass.kt new file mode 100644 index 00000000000..6495208be53 --- /dev/null +++ b/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromInlineLambdaInNestedClass.kt @@ -0,0 +1,17 @@ +// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField + +inline fun run(fn: () -> T) = fn() + +class Outer { + private companion object { + val result = "OK" + } + + class Nested { + fun foo() = run { result } + } + + fun test() = Nested().foo() +} + +fun box() = Outer().test() \ No newline at end of file diff --git a/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromLambdaInNestedClass.kt b/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromLambdaInNestedClass.kt new file mode 100644 index 00000000000..661ab5543be --- /dev/null +++ b/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromLambdaInNestedClass.kt @@ -0,0 +1,15 @@ +// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField + +class Outer { + private companion object { + val result = "OK" + } + + class Nested { + fun foo() = { result }() + } + + fun test() = Nested().foo() +} + +fun box() = Outer().test() \ No newline at end of file diff --git a/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromMethodInlinedInNestedClass.kt b/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromMethodInlinedInNestedClass.kt new file mode 100644 index 00000000000..aaa63fc49f1 --- /dev/null +++ b/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromMethodInlinedInNestedClass.kt @@ -0,0 +1,17 @@ +// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField + +class Outer { + private companion object { + val result = "OK" + } + + private inline fun bar() = result + + class Nested { + fun foo(x: Outer) = x.bar() + } + + fun test() = Nested().foo(this) +} + +fun box() = Outer().test() \ No newline at end of file diff --git a/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClass.kt b/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClass.kt new file mode 100644 index 00000000000..588f0dfcd54 --- /dev/null +++ b/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClass.kt @@ -0,0 +1,15 @@ +// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField + +class Outer { + private companion object { + val result = "OK" + } + + class Nested { + fun foo() = result + } + + fun test() = Nested().foo() +} + +fun box() = Outer().test() \ No newline at end of file diff --git a/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClassSeveralTimes.kt b/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClassSeveralTimes.kt new file mode 100644 index 00000000000..9f10e2ba1cb --- /dev/null +++ b/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClassSeveralTimes.kt @@ -0,0 +1,20 @@ +// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField + +class Outer { + private companion object { + fun xo() = "O" + fun xk() = "K" + } + + class Nested1 { + fun foo() = xo() + } + + class Nested2 { + fun bar() = xk() + } + + fun test() = Nested1().foo() + Nested2().bar() +} + +fun box() = Outer().test() \ No newline at end of file diff --git a/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectUsedInNestedClass.kt b/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectUsedInNestedClass.kt new file mode 100644 index 00000000000..1a6027bd5cd --- /dev/null +++ b/compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectUsedInNestedClass.kt @@ -0,0 +1,15 @@ +// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField + +class Outer { + private companion object { + override fun toString(): String = "OK" + } + + class Nested { + fun foo(): Any = Outer.Companion + } + + fun test() = Nested().foo().toString() +} + +fun box() = Outer().test() \ No newline at end of file diff --git a/compiler/testData/codegen/box/objects/companionObjectAccess/protectedCompanionObjectAccessedFromNestedClass.kt b/compiler/testData/codegen/box/objects/companionObjectAccess/protectedCompanionObjectAccessedFromNestedClass.kt new file mode 100644 index 00000000000..505151fbbbe --- /dev/null +++ b/compiler/testData/codegen/box/objects/companionObjectAccess/protectedCompanionObjectAccessedFromNestedClass.kt @@ -0,0 +1,15 @@ +// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField + +class Outer { + protected companion object { + val result = "OK" + } + + class Nested { + fun foo() = result + } + + fun test() = Nested().foo() +} + +fun box() = Outer().test() \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/noSyntheticAccessorForPrivateCompanionObjectWhenNotRequired.kt b/compiler/testData/codegen/bytecodeText/noSyntheticAccessorForPrivateCompanionObjectWhenNotRequired.kt new file mode 100644 index 00000000000..1e0e2d17d3a --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/noSyntheticAccessorForPrivateCompanionObjectWhenNotRequired.kt @@ -0,0 +1,14 @@ +class Outer { + private companion object { + val result = "OK" + + fun bar() = result + } + + fun test() = bar() + +} + +// 0 access\$Companion +// 1 INVOKEVIRTUAL Outer\$Companion\.bar +// 1 INVOKEVIRTUAL Outer\$Companion\.getResult \ No newline at end of file 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 ed6bcb6e5de..70cc64b0ef1 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 @@ -14016,6 +14016,59 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes public void testUseImportedMemberFromCompanion() throws Exception { runTest("compiler/testData/codegen/box/objects/useImportedMemberFromCompanion.kt"); } + + @TestMetadata("compiler/testData/codegen/box/objects/companionObjectAccess") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class CompanionObjectAccess extends AbstractIrBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInCompanionObjectAccess() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromInlineLambdaInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromInlineLambdaInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromInlineLambdaInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromLambdaInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromLambdaInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromLambdaInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromMethodInlinedInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromMethodInlinedInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromMethodInlinedInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromNestedClassSeveralTimes.kt") + public void testPrivateCompanionObjectAccessedFromNestedClassSeveralTimes() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClassSeveralTimes.kt"); + } + + @TestMetadata("privateCompanionObjectUsedInNestedClass.kt") + public void testPrivateCompanionObjectUsedInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectUsedInNestedClass.kt"); + } + + @TestMetadata("protectedCompanionObjectAccessedFromNestedClass.kt") + public void testProtectedCompanionObjectAccessedFromNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/protectedCompanionObjectAccessedFromNestedClass.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/operatorConventions") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index d410401b35f..45687454cc8 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -14016,6 +14016,59 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testUseImportedMemberFromCompanion() throws Exception { runTest("compiler/testData/codegen/box/objects/useImportedMemberFromCompanion.kt"); } + + @TestMetadata("compiler/testData/codegen/box/objects/companionObjectAccess") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class CompanionObjectAccess extends AbstractBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInCompanionObjectAccess() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromInlineLambdaInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromInlineLambdaInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromInlineLambdaInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromLambdaInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromLambdaInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromLambdaInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromMethodInlinedInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromMethodInlinedInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromMethodInlinedInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromNestedClassSeveralTimes.kt") + public void testPrivateCompanionObjectAccessedFromNestedClassSeveralTimes() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClassSeveralTimes.kt"); + } + + @TestMetadata("privateCompanionObjectUsedInNestedClass.kt") + public void testPrivateCompanionObjectUsedInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectUsedInNestedClass.kt"); + } + + @TestMetadata("protectedCompanionObjectAccessedFromNestedClass.kt") + public void testProtectedCompanionObjectAccessedFromNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/protectedCompanionObjectAccessedFromNestedClass.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/operatorConventions") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index c93fb61a2d8..26dc8fe93e9 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -274,6 +274,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/noSuperCheckInDefaultConstuctor.kt"); } + @TestMetadata("noSyntheticAccessorForPrivateCompanionObjectWhenNotRequired.kt") + public void testNoSyntheticAccessorForPrivateCompanionObjectWhenNotRequired() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/noSyntheticAccessorForPrivateCompanionObjectWhenNotRequired.kt"); + } + @TestMetadata("noWrapperForMethodReturningPrimitive.kt") public void testNoWrapperForMethodReturningPrimitive() throws Exception { runTest("compiler/testData/codegen/bytecodeText/noWrapperForMethodReturningPrimitive.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index c5fb6b61811..65c5da2e5e2 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -14016,6 +14016,59 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testUseImportedMemberFromCompanion() throws Exception { runTest("compiler/testData/codegen/box/objects/useImportedMemberFromCompanion.kt"); } + + @TestMetadata("compiler/testData/codegen/box/objects/companionObjectAccess") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class CompanionObjectAccess extends AbstractLightAnalysisModeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInCompanionObjectAccess() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromInlineLambdaInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromInlineLambdaInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromInlineLambdaInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromLambdaInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromLambdaInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromLambdaInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromMethodInlinedInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromMethodInlinedInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromMethodInlinedInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromNestedClassSeveralTimes.kt") + public void testPrivateCompanionObjectAccessedFromNestedClassSeveralTimes() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClassSeveralTimes.kt"); + } + + @TestMetadata("privateCompanionObjectUsedInNestedClass.kt") + public void testPrivateCompanionObjectUsedInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectUsedInNestedClass.kt"); + } + + @TestMetadata("protectedCompanionObjectAccessedFromNestedClass.kt") + public void testProtectedCompanionObjectAccessedFromNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/protectedCompanionObjectAccessedFromNestedClass.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/operatorConventions") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java index bad78857d20..7661d010df6 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java @@ -13346,6 +13346,59 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { public void testUseImportedMemberFromCompanion() throws Exception { runTest("compiler/testData/codegen/box/objects/useImportedMemberFromCompanion.kt"); } + + @TestMetadata("compiler/testData/codegen/box/objects/companionObjectAccess") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class CompanionObjectAccess extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInCompanionObjectAccess() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true); + } + + @TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromInlineLambdaInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromInlineLambdaInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromInlineLambdaInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromLambdaInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromLambdaInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromLambdaInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromMethodInlinedInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromMethodInlinedInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromMethodInlinedInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromNestedClassSeveralTimes.kt") + public void testPrivateCompanionObjectAccessedFromNestedClassSeveralTimes() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClassSeveralTimes.kt"); + } + + @TestMetadata("privateCompanionObjectUsedInNestedClass.kt") + public void testPrivateCompanionObjectUsedInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectUsedInNestedClass.kt"); + } + + @TestMetadata("protectedCompanionObjectAccessedFromNestedClass.kt") + public void testProtectedCompanionObjectAccessedFromNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/protectedCompanionObjectAccessedFromNestedClass.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/operatorConventions") 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 e3cd59048c6..dd6b7d79201 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 @@ -12218,6 +12218,59 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { public void testUseImportedMemberFromCompanion() throws Exception { runTest("compiler/testData/codegen/box/objects/useImportedMemberFromCompanion.kt"); } + + @TestMetadata("compiler/testData/codegen/box/objects/companionObjectAccess") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class CompanionObjectAccess extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInCompanionObjectAccess() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/objects/companionObjectAccess"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + + @TestMetadata("privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromAnonymousObjectInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromAnonymousObjectInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromInlineLambdaInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromInlineLambdaInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromInlineLambdaInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromLambdaInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromLambdaInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromLambdaInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromMethodInlinedInNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromMethodInlinedInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromMethodInlinedInNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromNestedClass.kt") + public void testPrivateCompanionObjectAccessedFromNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClass.kt"); + } + + @TestMetadata("privateCompanionObjectAccessedFromNestedClassSeveralTimes.kt") + public void testPrivateCompanionObjectAccessedFromNestedClassSeveralTimes() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectAccessedFromNestedClassSeveralTimes.kt"); + } + + @TestMetadata("privateCompanionObjectUsedInNestedClass.kt") + public void testPrivateCompanionObjectUsedInNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/privateCompanionObjectUsedInNestedClass.kt"); + } + + @TestMetadata("protectedCompanionObjectAccessedFromNestedClass.kt") + public void testProtectedCompanionObjectAccessedFromNestedClass() throws Exception { + runTest("compiler/testData/codegen/box/objects/companionObjectAccess/protectedCompanionObjectAccessedFromNestedClass.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/operatorConventions")