Generate package private visibility in bytecode for private classes

This commit is contained in:
Michael Bogdanov
2016-02-01 17:26:05 +03:00
parent 751ac3912d
commit 71c2a6e792
8 changed files with 20 additions and 21 deletions
@@ -257,8 +257,7 @@ public class AsmUtil {
Classes in byte code should be public or package private Classes in byte code should be public or package private
*/ */
public static int getVisibilityAccessFlagForClass(ClassDescriptor descriptor) { public static int getVisibilityAccessFlagForClass(ClassDescriptor descriptor) {
if (DescriptorUtils.isTopLevelDeclaration(descriptor) || if (descriptor.getVisibility() == Visibilities.PUBLIC ||
descriptor.getVisibility() == Visibilities.PUBLIC ||
// TODO: should be package private, but for now Kotlin's reflection can't access members of such classes // TODO: should be package private, but for now Kotlin's reflection can't access members of such classes
descriptor.getVisibility() == Visibilities.LOCAL || descriptor.getVisibility() == Visibilities.LOCAL ||
descriptor.getVisibility() == Visibilities.INTERNAL) { descriptor.getVisibility() == Visibilities.INTERNAL) {
@@ -284,13 +284,12 @@ open class KtLightClassForExplicitDeclaration(
} }
if (classOrObject.hasModifier(PRIVATE_KEYWORD)) { if (classOrObject.hasModifier(PRIVATE_KEYWORD)) {
// Top-level private class has PUBLIC visibility in Java // Top-level private class has PACKAGE_LOCAL visibility in Java
// Nested private class has PRIVATE visibility // Nested private class has PRIVATE visibility
psiModifiers.add(if (classOrObject.isTopLevel()) PsiModifier.PUBLIC else PsiModifier.PRIVATE) psiModifiers.add(if (classOrObject.isTopLevel()) PsiModifier.PACKAGE_LOCAL else PsiModifier.PRIVATE)
} }
else if (!psiModifiers.contains(PsiModifier.PROTECTED)) {
if (!psiModifiers.contains(PsiModifier.PRIVATE) && !psiModifiers.contains(PsiModifier.PROTECTED)) { psiModifiers.add(PsiModifier.PUBLIC)
psiModifiers.add(PsiModifier.PUBLIC) // For internal (default) visibility
} }
@@ -4,4 +4,4 @@ private class MyClass() {
// TESTED_OBJECT_KIND: class // TESTED_OBJECT_KIND: class
// TESTED_OBJECTS: MyClass // TESTED_OBJECTS: MyClass
// FLAGS: ACC_FINAL, ACC_PUBLIC, ACC_SUPER // FLAGS: ACC_FINAL, ACC_SUPER
@@ -3,4 +3,4 @@ private enum class MyClass() {
// TESTED_OBJECT_KIND: class // TESTED_OBJECT_KIND: class
// TESTED_OBJECTS: MyClass // TESTED_OBJECTS: MyClass
// FLAGS: ACC_FINAL, ACC_PUBLIC, ACC_SUPER, ACC_ENUM // FLAGS: ACC_FINAL, ACC_SUPER, ACC_ENUM
@@ -3,4 +3,4 @@ private object MyClass {
// TESTED_OBJECT_KIND: class // TESTED_OBJECT_KIND: class
// TESTED_OBJECTS: MyClass // TESTED_OBJECTS: MyClass
// FLAGS: ACC_FINAL, ACC_PUBLIC, ACC_SUPER // FLAGS: ACC_FINAL, ACC_SUPER
@@ -3,4 +3,4 @@ private interface MyClass {
// TESTED_OBJECT_KIND: class // TESTED_OBJECT_KIND: class
// TESTED_OBJECTS: MyClass // TESTED_OBJECTS: MyClass
// FLAGS: ACC_ABSTRACT, ACC_INTERFACE, ACC_PUBLIC // FLAGS: ACC_ABSTRACT, ACC_INTERFACE
@@ -54,7 +54,7 @@ public abstract class KotlinLightClassStructureTest extends KotlinAsJavaTestBase
public void testTopLevelVisibilities() { public void testTopLevelVisibilities() {
checkModifiers("test.Public", PUBLIC, FINAL); checkModifiers("test.Public", PUBLIC, FINAL);
checkModifiers("test.Private", PUBLIC, FINAL); checkModifiers("test.Private", PACKAGE_LOCAL, FINAL);
checkModifiers("test.Internal", PUBLIC, FINAL); checkModifiers("test.Internal", PUBLIC, FINAL);
} }
@@ -253,6 +253,7 @@ public abstract class KotlinLightClassStructureTest extends KotlinAsJavaTestBase
enum ClassProperty { enum ClassProperty {
PUBLIC(PsiModifier.PUBLIC), PUBLIC(PsiModifier.PUBLIC),
PROTECTED(PsiModifier.PROTECTED), PROTECTED(PsiModifier.PROTECTED),
PACKAGE_LOCAL(PsiModifier.PACKAGE_LOCAL),
PRIVATE(PsiModifier.PRIVATE), PRIVATE(PsiModifier.PRIVATE),
STATIC(PsiModifier.STATIC), STATIC(PsiModifier.STATIC),
ABSTRACT(PsiModifier.ABSTRACT), ABSTRACT(PsiModifier.ABSTRACT),
@@ -16,7 +16,7 @@
package kotlin.jvm.internal package kotlin.jvm.internal
private object DoubleCompanionObject { internal object DoubleCompanionObject {
val MIN_VALUE: Double = java.lang.Double.MIN_VALUE val MIN_VALUE: Double = java.lang.Double.MIN_VALUE
val MAX_VALUE: Double = java.lang.Double.MAX_VALUE val MAX_VALUE: Double = java.lang.Double.MAX_VALUE
val POSITIVE_INFINITY : Double = java.lang.Double.POSITIVE_INFINITY val POSITIVE_INFINITY : Double = java.lang.Double.POSITIVE_INFINITY
@@ -24,7 +24,7 @@ private object DoubleCompanionObject {
val NaN : Double = java.lang.Double.NaN val NaN : Double = java.lang.Double.NaN
} }
private object FloatCompanionObject { internal object FloatCompanionObject {
val MIN_VALUE: Float = java.lang.Float.MIN_VALUE val MIN_VALUE: Float = java.lang.Float.MIN_VALUE
val MAX_VALUE: Float = java.lang.Float.MAX_VALUE val MAX_VALUE: Float = java.lang.Float.MAX_VALUE
val POSITIVE_INFINITY : Float = java.lang.Float.POSITIVE_INFINITY val POSITIVE_INFINITY : Float = java.lang.Float.POSITIVE_INFINITY
@@ -32,28 +32,28 @@ private object FloatCompanionObject {
val NaN : Float = java.lang.Float.NaN val NaN : Float = java.lang.Float.NaN
} }
private object IntCompanionObject { internal object IntCompanionObject {
const val MIN_VALUE: Int = java.lang.Integer.MIN_VALUE const val MIN_VALUE: Int = java.lang.Integer.MIN_VALUE
const val MAX_VALUE: Int = java.lang.Integer.MAX_VALUE const val MAX_VALUE: Int = java.lang.Integer.MAX_VALUE
} }
private object LongCompanionObject { internal object LongCompanionObject {
const val MIN_VALUE: Long = java.lang.Long.MIN_VALUE const val MIN_VALUE: Long = java.lang.Long.MIN_VALUE
const val MAX_VALUE: Long = java.lang.Long.MAX_VALUE const val MAX_VALUE: Long = java.lang.Long.MAX_VALUE
} }
private object ShortCompanionObject { internal object ShortCompanionObject {
const val MIN_VALUE: Short = java.lang.Short.MIN_VALUE const val MIN_VALUE: Short = java.lang.Short.MIN_VALUE
const val MAX_VALUE: Short = java.lang.Short.MAX_VALUE const val MAX_VALUE: Short = java.lang.Short.MAX_VALUE
} }
private object ByteCompanionObject { internal object ByteCompanionObject {
const val MIN_VALUE: Byte = java.lang.Byte.MIN_VALUE const val MIN_VALUE: Byte = java.lang.Byte.MIN_VALUE
const val MAX_VALUE: Byte = java.lang.Byte.MAX_VALUE const val MAX_VALUE: Byte = java.lang.Byte.MAX_VALUE
} }
private object CharCompanionObject { internal object CharCompanionObject {
const val MIN_HIGH_SURROGATE: Char = '\uD800' const val MIN_HIGH_SURROGATE: Char = '\uD800'
const val MAX_HIGH_SURROGATE: Char = '\uDBFF' const val MAX_HIGH_SURROGATE: Char = '\uDBFF'
const val MIN_LOW_SURROGATE: Char = '\uDC00' const val MIN_LOW_SURROGATE: Char = '\uDC00'
@@ -62,5 +62,5 @@ private object CharCompanionObject {
const val MAX_SURROGATE: Char = MAX_LOW_SURROGATE const val MAX_SURROGATE: Char = MAX_LOW_SURROGATE
} }
private object StringCompanionObject {} internal object StringCompanionObject {}
private object EnumCompanionObject {} internal object EnumCompanionObject {}