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 47fe426131b..312336d110a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java @@ -206,7 +206,26 @@ public abstract class CodegenContext { @NotNull public ClassContext intoClass(ClassDescriptor descriptor, OwnerKind kind, GenerationState state) { - return new ClassContext(state.getTypeMapper(), descriptor, kind, this, null); + if (descriptor.isCompanionObject()) { + CodegenContext companionContext = this.findChildContext(descriptor); + if (companionContext != null) { + assert companionContext.getContextKind() == kind : "Kinds should be same, but: " + + companionContext.getContextKind() + "!= " + kind; + return (ClassContext) companionContext; + } + } + ClassContext classContext = new ClassContext(state.getTypeMapper(), descriptor, kind, this, null); + + //We can't call descriptor.getCompanionObjectDescriptor() on light class generation + // because it triggers companion light class generation via putting it to BindingContext.CLASS + // (so MemberCodegen doesn't skip it in genClassOrObject). + if (state.getTypeMapper().getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES && + descriptor.getCompanionObjectDescriptor() != null) { + //We need to create companion object context ahead of time + // because otherwise we can't generate synthetic accessor for private members in companion object + classContext.intoClass(descriptor.getCompanionObjectDescriptor(), OwnerKind.IMPLEMENTATION, state); + } + return classContext; } @NotNull diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/NeedSyntheticChecker.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/NeedSyntheticChecker.java index b89c7b7493c..a39436bf670 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/NeedSyntheticChecker.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/NeedSyntheticChecker.java @@ -43,7 +43,7 @@ public class NeedSyntheticChecker implements CallChecker { //Necessary synthetic accessors in outer classes generated via old logic: CodegenContext.getAccessor //Generation of accessors in nested classes (to invoke from outer, // e.g.: from class to companion object) controlled via NEED_SYNTHETIC_ACCESSOR slice - private boolean needSyntheticAccessor(LexicalScope invokationScope, CallableDescriptor targetDescriptor) { + private static boolean needSyntheticAccessor(LexicalScope invokationScope, CallableDescriptor targetDescriptor) { return targetDescriptor instanceof CallableMemberDescriptor && Visibilities.isPrivate(targetDescriptor.getVisibility()) && targetDescriptor.getContainingDeclaration() != invokationScope.getOwnerDescriptor().getContainingDeclaration(); diff --git a/compiler/testData/codegen/box/innerNested/kt5363.kt b/compiler/testData/codegen/box/innerNested/kt5363.kt new file mode 100644 index 00000000000..1f696893d3d --- /dev/null +++ b/compiler/testData/codegen/box/innerNested/kt5363.kt @@ -0,0 +1,13 @@ +class Outer { + class Nested{ + fun foo(s: String) = s.extension() + } + + companion object { + private fun String.extension(): String = this + } +} + +fun box(): String { + return Outer.Nested().foo("OK") +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/innerNested/kt6804.kt b/compiler/testData/codegen/box/innerNested/kt6804.kt new file mode 100644 index 00000000000..edb201a622e --- /dev/null +++ b/compiler/testData/codegen/box/innerNested/kt6804.kt @@ -0,0 +1,13 @@ +class Outer { + class Nested { + fun fn() = s + } + + companion object { + private val s = "OK" + } +} + +fun box(): String { + return Outer.Nested().fn() +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java index 7d84f66bd3d..ea37e068357 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -4498,6 +4498,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("kt5363.kt") + public void testKt5363() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/innerNested/kt5363.kt"); + doTest(fileName); + } + + @TestMetadata("kt6804.kt") + public void testKt6804() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/innerNested/kt6804.kt"); + doTest(fileName); + } + @TestMetadata("nestedClassInObject.kt") public void testNestedClassInObject() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/innerNested/nestedClassInObject.kt");