Generate private constructors for Enums

#KT-2680 Fixed
  #KT-16867 Fixed
This commit is contained in:
Mikhael Bogdanov
2018-09-18 10:32:21 +02:00
parent c753a98d02
commit 38652372ce
11 changed files with 99 additions and 14 deletions
@@ -549,16 +549,8 @@ public class AsmUtil {
return NO_FLAG_PACKAGE_PRIVATE; return NO_FLAG_PACKAGE_PRIVATE;
} }
// the following code is only for PRIVATE visibility of member if (memberDescriptor instanceof ConstructorDescriptor && isEnumEntry(containingDeclaration)) {
if (memberDescriptor instanceof ConstructorDescriptor) { return NO_FLAG_PACKAGE_PRIVATE;
if (isEnumEntry(containingDeclaration)) {
return NO_FLAG_PACKAGE_PRIVATE;
}
if (isEnumClass(containingDeclaration)) {
//TODO: should be ACC_PRIVATE
// see http://youtrack.jetbrains.com/issue/KT-2680
return ACC_PROTECTED;
}
} }
return null; return null;
@@ -70,6 +70,7 @@ import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNullableAny;
import static org.jetbrains.kotlin.codegen.AsmUtil.*; import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.generateBridgeForMainFunctionIfNecessary; import static org.jetbrains.kotlin.codegen.CodegenUtilKt.generateBridgeForMainFunctionIfNecessary;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION; import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
import static org.jetbrains.kotlin.codegen.state.KotlinTypeMapper.isAccessor;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION; import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable; import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable;
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isEffectivelyInlineOnly; import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isEffectivelyInlineOnly;
@@ -353,7 +354,7 @@ public class FunctionCodegen {
// base check // base check
boolean isInlineClass = InlineClassesUtilsKt.isInlineClass(containingDeclaration); boolean isInlineClass = InlineClassesUtilsKt.isInlineClass(containingDeclaration);
boolean simpleFunctionOrProperty = boolean simpleFunctionOrProperty =
!(functionDescriptor instanceof ConstructorDescriptor) && !KotlinTypeMapper.isAccessor(functionDescriptor); !(functionDescriptor instanceof ConstructorDescriptor) && !isAccessor(functionDescriptor);
return isInlineClass && simpleFunctionOrProperty; return isInlineClass && simpleFunctionOrProperty;
} }
@@ -511,12 +512,14 @@ public class FunctionCodegen {
KotlinTypeMapper typeMapper = state.getTypeMapper(); KotlinTypeMapper typeMapper = state.getTypeMapper();
Iterator<ValueParameterDescriptor> iterator = valueParameters.iterator(); Iterator<ValueParameterDescriptor> iterator = valueParameters.iterator();
List<JvmMethodParameterSignature> kotlinParameterTypes = jvmSignature.getValueParameters(); List<JvmMethodParameterSignature> kotlinParameterTypes = jvmSignature.getValueParameters();
boolean isAccessor = isAccessor(functionDescriptor);
for (int i = 0; i < kotlinParameterTypes.size(); i++) { for (int i = 0; i < kotlinParameterTypes.size(); i++) {
JvmMethodParameterSignature parameterSignature = kotlinParameterTypes.get(i); JvmMethodParameterSignature parameterSignature = kotlinParameterTypes.get(i);
JvmMethodParameterKind kind = parameterSignature.getKind(); JvmMethodParameterKind kind = parameterSignature.getKind();
if (kind.isSkippedInGenericSignature()) { if (kind.isSkippedInGenericSignature()) {
markEnumOrInnerConstructorParameterAsSynthetic(mv, i, state.getClassBuilderMode()); if (!isAccessor)
markEnumOrInnerConstructorParameterAsSynthetic(mv, i, state.getClassBuilderMode());
continue; continue;
} }
@@ -9,5 +9,5 @@ public enum E {
@kotlin.Deprecated(message = "b") @kotlin.Deprecated(message = "b")
Entry3; Entry3;
protected E() { /* compiled code */ } private E() { /* compiled code */ }
} }
@@ -0,0 +1,23 @@
// TARGET_BACKEND: JVM
// FILE: Foo.java
public class Foo {
static String test() {
return KEnum.O.name() + KEnum.O.getValue();
}
}
// FILE: KEnum.kt
@Retention(AnnotationRetention.RUNTIME)
annotation class A
enum class KEnum(@A val value: Any) {
O("K")
}
fun box(): String {
return Foo.test();
}
@@ -0,0 +1,25 @@
// TARGET_BACKEND: JVM
// FILE: Foo.java
public class Foo {
static String test() {
return KEnum.O.name() + KEnum.O.getValue();
}
}
// FILE: KEnum.kt
@Retention(AnnotationRetention.RUNTIME)
annotation class A
enum class KEnum(@A val value: Any) {
O("K") {
fun foo() {}
}
}
fun box(): String {
return Foo.test()
}
@@ -26,7 +26,7 @@ public final enum class TestEnum {
public final static field ANSWER: TestEnum public final static field ANSWER: TestEnum
private final field z: int private final field z: int
static method <clinit>(): void static method <clinit>(): void
protected method <init>(p0: java.lang.String, p1: int, p2: int): void private method <init>(p0: java.lang.String, p1: int, p2: int): void
public final method getZ(): int public final method getZ(): int
public static method valueOf(p0: java.lang.String): TestEnum public static method valueOf(p0: java.lang.String): TestEnum
public static method values(): TestEnum[] public static method values(): TestEnum[]
@@ -0,0 +1,7 @@
enum class Foo {
A, B, C
}
// TESTED_OBJECT_KIND: function
// TESTED_OBJECTS: Foo, <init>
// FLAGS: ACC_PRIVATE
@@ -9598,6 +9598,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/enum"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/enum"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
} }
@TestMetadata("annotatedParameter.kt")
public void testAnnotatedParameter() throws Exception {
runTest("compiler/testData/codegen/box/enum/annotatedParameter.kt");
}
@TestMetadata("annotatedParameter2.kt")
public void testAnnotatedParameter2() throws Exception {
runTest("compiler/testData/codegen/box/enum/annotatedParameter2.kt");
}
@TestMetadata("asReturnExpression.kt") @TestMetadata("asReturnExpression.kt")
public void testAsReturnExpression() throws Exception { public void testAsReturnExpression() throws Exception {
runTest("compiler/testData/codegen/box/enum/asReturnExpression.kt"); runTest("compiler/testData/codegen/box/enum/asReturnExpression.kt");
@@ -9598,6 +9598,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/enum"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/enum"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
} }
@TestMetadata("annotatedParameter.kt")
public void testAnnotatedParameter() throws Exception {
runTest("compiler/testData/codegen/box/enum/annotatedParameter.kt");
}
@TestMetadata("annotatedParameter2.kt")
public void testAnnotatedParameter2() throws Exception {
runTest("compiler/testData/codegen/box/enum/annotatedParameter2.kt");
}
@TestMetadata("asReturnExpression.kt") @TestMetadata("asReturnExpression.kt")
public void testAsReturnExpression() throws Exception { public void testAsReturnExpression() throws Exception {
runTest("compiler/testData/codegen/box/enum/asReturnExpression.kt"); runTest("compiler/testData/codegen/box/enum/asReturnExpression.kt");
@@ -462,6 +462,11 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest {
runTest("compiler/testData/writeFlags/function/constructors/classObject.kt"); runTest("compiler/testData/writeFlags/function/constructors/classObject.kt");
} }
@TestMetadata("enum.kt")
public void testEnum() throws Exception {
runTest("compiler/testData/writeFlags/function/constructors/enum.kt");
}
@TestMetadata("objectInClass.kt") @TestMetadata("objectInClass.kt")
public void testObjectInClass() throws Exception { public void testObjectInClass() throws Exception {
runTest("compiler/testData/writeFlags/function/constructors/objectInClass.kt"); runTest("compiler/testData/writeFlags/function/constructors/objectInClass.kt");
@@ -9598,6 +9598,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/enum"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/enum"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
} }
@TestMetadata("annotatedParameter.kt")
public void testAnnotatedParameter() throws Exception {
runTest("compiler/testData/codegen/box/enum/annotatedParameter.kt");
}
@TestMetadata("annotatedParameter2.kt")
public void testAnnotatedParameter2() throws Exception {
runTest("compiler/testData/codegen/box/enum/annotatedParameter2.kt");
}
@TestMetadata("asReturnExpression.kt") @TestMetadata("asReturnExpression.kt")
public void testAsReturnExpression() throws Exception { public void testAsReturnExpression() throws Exception {
runTest("compiler/testData/codegen/box/enum/asReturnExpression.kt"); runTest("compiler/testData/codegen/box/enum/asReturnExpression.kt");