Private visibility for non-const, non-jvmField class companion property backing field

This commit is contained in:
Michael Bogdanov
2015-12-25 15:05:31 +03:00
parent 85ae0cb78e
commit e116cc3206
76 changed files with 299 additions and 157 deletions
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JavaVisibilities;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
import org.jetbrains.kotlin.resolve.DeprecationUtilKt;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
@@ -61,6 +62,7 @@ import java.util.Set;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isBoolean;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveClass;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_SYNTHETIC_CLASS;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
@@ -681,13 +683,13 @@ public class AsmUtil {
isObject(propertyDescriptor.getContainingDeclaration());
}
public static int getVisibilityForSpecialPropertyBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) {
public static int getVisibilityForBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) {
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
if (isDelegate || isExtensionProperty) {
return ACC_PRIVATE;
}
else {
return areBothAccessorDefault(propertyDescriptor)
return propertyDescriptor.isLateInit() || isConstOrHasJvmFieldAnnotation(propertyDescriptor)
? getVisibilityAccessFlag(descriptorForVisibility(propertyDescriptor))
: ACC_PRIVATE;
}
@@ -706,16 +708,7 @@ public class AsmUtil {
DeclarationDescriptor propertyContainer = propertyDescriptor.getContainingDeclaration();
return propertyDescriptor.isConst()
&& isCompanionObject(propertyContainer) && isInterface(propertyContainer.getContainingDeclaration())
&& getVisibilityForSpecialPropertyBackingField(propertyDescriptor, false) == ACC_PUBLIC;
}
private static boolean areBothAccessorDefault(@NotNull PropertyDescriptor propertyDescriptor) {
return isAccessorWithEmptyBody(propertyDescriptor.getGetter())
&& (!propertyDescriptor.isVar() || isAccessorWithEmptyBody(propertyDescriptor.getSetter()));
}
private static boolean isAccessorWithEmptyBody(@Nullable PropertyAccessorDescriptor accessorDescriptor) {
return accessorDescriptor == null || !accessorDescriptor.hasBody();
&& getVisibilityForBackingField(propertyDescriptor, false) == ACC_PUBLIC;
}
public static Type comparisonOperandType(Type left, Type right) {
@@ -2140,7 +2140,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
PropertyDescriptor originalPropertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor);
if (fieldAccessorKind != FieldAccessorKind.NORMAL) {
int flags = AsmUtil.getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegatedProperty);
int flags = AsmUtil.getVisibilityForBackingField(propertyDescriptor, isDelegatedProperty);
skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || skipAccessorsForPrivateFieldInOuterClass;
if (!skipPropertyAccessors) {
//noinspection ConstantConditions
@@ -54,12 +54,14 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.AsmUtil.getDeprecatedAccessFlag;
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityForBackingField;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.FIELD_FOR_PROPERTY;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.K_PROPERTY_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.annotations.AnnotationUtilKt.hasJvmFieldAnnotation;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
@@ -300,50 +302,17 @@ public class PropertyCodegen {
ClassBuilder builder = v;
boolean hasJvmFieldAnnotation = hasJvmFieldAnnotation(propertyDescriptor);
FieldOwnerContext backingFieldContext = context;
boolean takeVisibilityFromDescriptor = propertyDescriptor.isLateInit() || propertyDescriptor.isConst();
boolean takeVisibilityFromSetter = propertyDescriptor.isLateInit() && propertyDescriptor.getSetter() != null;
if (AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor) ) {
modifiers |= ACC_STATIC;
if (takeVisibilityFromDescriptor) {
modifiers |= getVisibilityAccessFlag(propertyDescriptor);
}
else if (hasJvmFieldAnnotation && !isDelegate) {
modifiers |= getDefaultVisibilityFlag(propertyDescriptor.getVisibility());
}
else {
modifiers |= getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegate);
}
if (JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
ImplementationBodyCodegen codegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
builder = codegen.v;
backingFieldContext = codegen.context;
}
if (isObject(propertyDescriptor.getContainingDeclaration()) &&
!hasJvmFieldAnnotation &&
!propertyDescriptor.isConst() &&
(modifiers & ACC_PRIVATE) == 0) {
modifiers |= ACC_DEPRECATED;
}
}
else if (takeVisibilityFromSetter) {
// For lateinits, we take visibility from setter, if any
modifiers |= getVisibilityAccessFlag(propertyDescriptor.getSetter());
}
else if (takeVisibilityFromDescriptor) {
modifiers |= getVisibilityAccessFlag(propertyDescriptor);
}
else if (!isDelegate && hasJvmFieldAnnotation) {
modifiers |= getDefaultVisibilityFlag(propertyDescriptor.getVisibility());
}
else {
modifiers |= ACC_PRIVATE;
}
modifiers |= getVisibilityForBackingField(propertyDescriptor, isDelegate);
if (AsmUtil.isPropertyWithBackingFieldCopyInOuterClass(propertyDescriptor)) {
ImplementationBodyCodegen parentBodyCodegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();