Support access to companion private members from nested classes
#KT-5363 Fixed #KT-6804 Fixed
This commit is contained in:
committed by
Max Kammerer
parent
3d88df73e0
commit
d977d29ec4
@@ -206,7 +206,26 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
|
||||
@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
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class Outer {
|
||||
class Nested {
|
||||
fun fn() = s
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val s = "OK"
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return Outer.Nested().fn()
|
||||
}
|
||||
+12
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user