Generate private interface companion object as package-private synthetic

This commit is contained in:
Dmitry Petrov
2018-09-25 15:40:50 +03:00
parent 7949ac1080
commit 792ff3c39e
14 changed files with 220 additions and 2 deletions
@@ -482,6 +482,10 @@ public class AsmUtil {
DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration();
Visibility memberVisibility = memberDescriptor.getVisibility(); Visibility memberVisibility = memberDescriptor.getVisibility();
if (JvmCodegenUtil.isNonIntrinsicPrivateCompanionObjectInInterface(memberDescriptor)) {
return ACC_PUBLIC;
}
if (memberDescriptor instanceof FunctionDescriptor && if (memberDescriptor instanceof FunctionDescriptor &&
isInlineClassWrapperConstructor((FunctionDescriptor) memberDescriptor, kind)) { isInlineClassWrapperConstructor((FunctionDescriptor) memberDescriptor, kind)) {
return ACC_PRIVATE; return ACC_PRIVATE;
@@ -786,12 +786,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.DeprecatedFieldForInvisibleCompanionObject); state.getLanguageVersionSettings().supportsFeature(LanguageFeature.DeprecatedFieldForInvisibleCompanionObject);
boolean properVisibilityForCompanionObjectInstanceField = boolean properVisibilityForCompanionObjectInstanceField =
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ProperVisibilityForCompanionObjectInstanceField); state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ProperVisibilityForCompanionObjectInstanceField);
boolean hasPrivateOrProtectedProperVisibility = (properFieldVisibilityFlag & (ACC_PRIVATE | ACC_PROTECTED)) != 0;
boolean hasPackagePrivateProperVisibility = (properFieldVisibilityFlag & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED)) == 0;
boolean fieldShouldBeDeprecated = boolean fieldShouldBeDeprecated =
deprecatedFieldForInvisibleCompanionObject && deprecatedFieldForInvisibleCompanionObject &&
!properVisibilityForCompanionObjectInstanceField && !properVisibilityForCompanionObjectInstanceField &&
(properFieldVisibilityFlag & (ACC_PRIVATE | ACC_PROTECTED)) != 0; (hasPrivateOrProtectedProperVisibility || hasPackagePrivateProperVisibility ||
isNonIntrinsicPrivateCompanionObjectInInterface(companionObjectDescriptor));
boolean doNotGeneratePublic = boolean doNotGeneratePublic =
properVisibilityForCompanionObjectInstanceField && (properFieldVisibilityFlag & (ACC_PRIVATE | ACC_PROTECTED)) != 0; properVisibilityForCompanionObjectInstanceField && hasPrivateOrProtectedProperVisibility;
int fieldAccessFlags; int fieldAccessFlags;
if (doNotGeneratePublic) { if (doNotGeneratePublic) {
fieldAccessFlags = ACC_STATIC | ACC_FINAL; fieldAccessFlags = ACC_STATIC | ACC_FINAL;
@@ -805,6 +808,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (fieldShouldBeDeprecated) { if (fieldShouldBeDeprecated) {
fieldAccessFlags |= ACC_DEPRECATED; fieldAccessFlags |= ACC_DEPRECATED;
} }
if (properVisibilityForCompanionObjectInstanceField &&
JvmCodegenUtil.isCompanionObjectInInterfaceNotIntrinsic(companionObjectDescriptor) &&
Visibilities.isPrivate(companionObjectDescriptor.getVisibility())) {
fieldAccessFlags |= ACC_SYNTHETIC;
}
StackValue.Field field = StackValue.singleton(companionObjectDescriptor, typeMapper); StackValue.Field field = StackValue.singleton(companionObjectDescriptor, typeMapper);
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(companionObject == null ? myClass.getPsiOrParent() : companionObject), FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(companionObject == null ? myClass.getPsiOrParent() : companionObject),
fieldAccessFlags, field.name, field.type.getDescriptor(), null, null); fieldAccessFlags, field.name, field.type.getDescriptor(), null, null);
@@ -348,6 +348,11 @@ public class JvmCodegenUtil {
!JvmAbi.isMappedIntrinsicCompanionObject((ClassDescriptor) companionObject); !JvmAbi.isMappedIntrinsicCompanionObject((ClassDescriptor) companionObject);
} }
public static boolean isNonIntrinsicPrivateCompanionObjectInInterface(@NotNull DeclarationDescriptorWithVisibility companionObject) {
return isCompanionObjectInInterfaceNotIntrinsic(companionObject) &&
Visibilities.isPrivate(companionObject.getVisibility());
}
public static boolean isDeclarationOfBigArityFunctionInvoke(@Nullable DeclarationDescriptor descriptor) { public static boolean isDeclarationOfBigArityFunctionInvoke(@Nullable DeclarationDescriptor descriptor) {
return descriptor instanceof FunctionInvokeDescriptor && ((FunctionInvokeDescriptor) descriptor).hasBigArity(); return descriptor instanceof FunctionInvokeDescriptor && ((FunctionInvokeDescriptor) descriptor).hasBigArity();
} }
@@ -0,0 +1,14 @@
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
// IGNORE_BACKEND: JS, JS_IR, JVM_IR
interface A {
fun test() = ok()
private companion object {
fun ok() = "OK"
}
}
class C : A
fun box() = C().test()
@@ -0,0 +1,17 @@
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
open class TestProtectedCompanionInClass {
protected companion object
}
class TestInternalCompanionInClass {
internal companion object
}
class TestPrivateCompanionInClass {
private companion object
}
interface TestPrivateCompanionInInterface {
private companion object
}
@@ -0,0 +1,59 @@
@kotlin.Metadata
public final class TestInternalCompanionInClass$Companion {
inner class TestInternalCompanionInClass$Companion
private method <init>(): void
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
}
@kotlin.Metadata
public final class TestInternalCompanionInClass {
public final static field Companion: TestInternalCompanionInClass$Companion
inner class TestInternalCompanionInClass$Companion
static method <clinit>(): void
public method <init>(): void
}
@kotlin.Metadata
final class TestPrivateCompanionInClass$Companion {
inner class TestPrivateCompanionInClass$Companion
private method <init>(): void
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
}
@kotlin.Metadata
public final class TestPrivateCompanionInClass {
private final static field Companion: TestPrivateCompanionInClass$Companion
inner class TestPrivateCompanionInClass$Companion
static method <clinit>(): void
public method <init>(): void
}
@kotlin.Metadata
final class TestPrivateCompanionInInterface$Companion {
synthetic final static field $$INSTANCE: TestPrivateCompanionInInterface$Companion
inner class TestPrivateCompanionInInterface$Companion
static method <clinit>(): void
private method <init>(): void
}
@kotlin.Metadata
public interface TestPrivateCompanionInInterface {
public synthetic final static field Companion: TestPrivateCompanionInInterface$Companion
inner class TestPrivateCompanionInInterface$Companion
static method <clinit>(): void
}
@kotlin.Metadata
public final class TestProtectedCompanionInClass$Companion {
inner class TestProtectedCompanionInClass$Companion
private method <init>(): void
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
}
@kotlin.Metadata
public class TestProtectedCompanionInClass {
protected final static field Companion: TestProtectedCompanionInClass$Companion
inner class TestProtectedCompanionInClass$Companion
static method <clinit>(): void
public method <init>(): void
}
@@ -0,0 +1,17 @@
// !LANGUAGE: -ProperVisibilityForCompanionObjectInstanceField
open class TestProtectedCompanionInClass {
protected companion object
}
class TestInternalCompanionInClass {
internal companion object
}
class TestPrivateCompanionInClass {
private companion object
}
interface TestPrivateCompanionInInterface {
private companion object
}
@@ -0,0 +1,59 @@
@kotlin.Metadata
public final class TestInternalCompanionInClass$Companion {
inner class TestInternalCompanionInClass$Companion
private method <init>(): void
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
}
@kotlin.Metadata
public final class TestInternalCompanionInClass {
public final static field Companion: TestInternalCompanionInClass$Companion
inner class TestInternalCompanionInClass$Companion
static method <clinit>(): void
public method <init>(): void
}
@kotlin.Metadata
final class TestPrivateCompanionInClass$Companion {
inner class TestPrivateCompanionInClass$Companion
private method <init>(): void
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
}
@kotlin.Metadata
public final class TestPrivateCompanionInClass {
public deprecated final static @java.lang.Deprecated field Companion: TestPrivateCompanionInClass$Companion
inner class TestPrivateCompanionInClass$Companion
static method <clinit>(): void
public method <init>(): void
}
@kotlin.Metadata
final class TestPrivateCompanionInInterface$Companion {
synthetic final static field $$INSTANCE: TestPrivateCompanionInInterface$Companion
inner class TestPrivateCompanionInInterface$Companion
static method <clinit>(): void
private method <init>(): void
}
@kotlin.Metadata
public interface TestPrivateCompanionInInterface {
public deprecated final static @java.lang.Deprecated field Companion: TestPrivateCompanionInInterface$Companion
inner class TestPrivateCompanionInInterface$Companion
static method <clinit>(): void
}
@kotlin.Metadata
public final class TestProtectedCompanionInClass$Companion {
inner class TestProtectedCompanionInClass$Companion
private method <init>(): void
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
}
@kotlin.Metadata
public class TestProtectedCompanionInClass {
public deprecated final static @java.lang.Deprecated field Companion: TestProtectedCompanionInClass$Companion
inner class TestProtectedCompanionInClass$Companion
static method <clinit>(): void
public method <init>(): void
}
@@ -15123,6 +15123,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt"); runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt");
} }
@TestMetadata("kt27121.kt")
public void testKt27121() throws Exception {
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27121.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");
@@ -38,6 +38,16 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
runTest("compiler/testData/codegen/bytecodeListing/callableNameIntrinsic.kt"); runTest("compiler/testData/codegen/bytecodeListing/callableNameIntrinsic.kt");
} }
@TestMetadata("companionObjectVisibility_after.kt")
public void testCompanionObjectVisibility_after() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/companionObjectVisibility_after.kt");
}
@TestMetadata("companionObjectVisibility_before.kt")
public void testCompanionObjectVisibility_before() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/companionObjectVisibility_before.kt");
}
@TestMetadata("coroutineContextIntrinsic.kt") @TestMetadata("coroutineContextIntrinsic.kt")
public void testCoroutineContextIntrinsic_1_2() throws Exception { public void testCoroutineContextIntrinsic_1_2() throws Exception {
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutineContextIntrinsic.kt", "kotlin.coroutines.experimental"); runTestWithPackageReplacement("compiler/testData/codegen/bytecodeListing/coroutineContextIntrinsic.kt", "kotlin.coroutines.experimental");
@@ -15123,6 +15123,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt"); runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt");
} }
@TestMetadata("kt27121.kt")
public void testKt27121() throws Exception {
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27121.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");
@@ -15128,6 +15128,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt"); runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt");
} }
@TestMetadata("kt27121.kt")
public void testKt27121() throws Exception {
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27121.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");
@@ -13308,6 +13308,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt"); runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt");
} }
@TestMetadata("kt27121.kt")
public void testKt27121() throws Exception {
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27121.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");
@@ -14353,6 +14353,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt"); runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27117.kt");
} }
@TestMetadata("kt27121.kt")
public void testKt27121() throws Exception {
runTest("compiler/testData/codegen/box/objects/companionObjectAccess/kt27121.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");