KT-2331 fix: proper dealing with privite property setters

This commit is contained in:
Alex Tkachman
2012-08-04 08:10:38 +03:00
parent 3f2e1bc1ce
commit bcec8b7c36
4 changed files with 62 additions and 32 deletions
@@ -193,8 +193,8 @@ public abstract class CodegenContext {
fd.getTypeParameters(), fd.getTypeParameters(),
fd.getValueParameters(), fd.getValueParameters(),
fd.getReturnType(), fd.getReturnType(),
fd.getModality(), Modality.FINAL,
fd.getVisibility(), Visibilities.PUBLIC,
/*isInline = */ false); /*isInline = */ false);
accessor = myAccessor; accessor = myAccessor;
} }
@@ -202,8 +202,8 @@ public abstract class CodegenContext {
PropertyDescriptor pd = (PropertyDescriptor) descriptor; PropertyDescriptor pd = (PropertyDescriptor) descriptor;
PropertyDescriptor myAccessor = new PropertyDescriptor(contextDescriptor, PropertyDescriptor myAccessor = new PropertyDescriptor(contextDescriptor,
Collections.<AnnotationDescriptor>emptyList(), Collections.<AnnotationDescriptor>emptyList(),
pd.getModality(), Modality.FINAL,
pd.getVisibility(), Visibilities.PUBLIC,
pd.isVar(), pd.isVar(),
pd.isObjectDeclaration(), pd.isObjectDeclaration(),
Name.identifier(pd.getName() + "$b$" + getHierarchyCount() + "$" + accessors.size()), Name.identifier(pd.getName() + "$b$" + getHierarchyCount() + "$" + accessors.size()),
@@ -213,15 +213,18 @@ public abstract class CodegenContext {
myAccessor.setType(pd.getType(), Collections.<TypeParameterDescriptorImpl>emptyList(), pd.getExpectedThisObject(), receiverType); myAccessor.setType(pd.getType(), Collections.<TypeParameterDescriptorImpl>emptyList(), pd.getExpectedThisObject(), receiverType);
PropertyGetterDescriptor pgd = new PropertyGetterDescriptor( PropertyGetterDescriptor pgd = new PropertyGetterDescriptor(
myAccessor, Collections.<AnnotationDescriptor>emptyList(), myAccessor.getModality(), myAccessor, Collections.<AnnotationDescriptor>emptyList(),
myAccessor.getVisibility(), Modality.FINAL,
Visibilities.PUBLIC,
false, false, CallableMemberDescriptor.Kind.DECLARATION); false, false, CallableMemberDescriptor.Kind.DECLARATION);
pgd.initialize(myAccessor.getType()); pgd.initialize(myAccessor.getType());
PropertySetterDescriptor psd = new PropertySetterDescriptor( PropertySetterDescriptor psd = new PropertySetterDescriptor(
myAccessor, Collections.<AnnotationDescriptor>emptyList(), myAccessor.getModality(), myAccessor, Collections.<AnnotationDescriptor>emptyList(),
myAccessor.getVisibility(), Modality.FINAL,
Visibilities.PUBLIC,
false, false, CallableMemberDescriptor.Kind.DECLARATION); false, false, CallableMemberDescriptor.Kind.DECLARATION);
myAccessor.initialize(pgd, psd); myAccessor.initialize(pgd, psd);
accessor = myAccessor; accessor = myAccessor;
} }
@@ -235,10 +238,11 @@ public abstract class CodegenContext {
private int getHierarchyCount() { private int getHierarchyCount() {
ClassDescriptor descriptor = getThisDescriptor(); ClassDescriptor descriptor = getThisDescriptor();
int c = 0; int c = 0;
while(true) { while(descriptor != null) {
Collection<? extends JetType> supertypes = descriptor.getDefaultType().getConstructor().getSupertypes(); Collection<? extends JetType> supertypes = descriptor.getDefaultType().getConstructor().getSupertypes();
if (supertypes.isEmpty()) if (supertypes.isEmpty()) {
return c; break;
}
c++; c++;
for (JetType supertype : supertypes) { for (JetType supertype : supertypes) {
descriptor = (ClassDescriptor) supertype.getConstructor().getDeclarationDescriptor(); descriptor = (ClassDescriptor) supertype.getConstructor().getDeclarationDescriptor();
@@ -247,6 +251,7 @@ public abstract class CodegenContext {
} }
} }
} }
return c;
} }
public StackValue getReceiverExpression(JetTypeMapper typeMapper) { public StackValue getReceiverExpression(JetTypeMapper typeMapper) {
@@ -1062,20 +1062,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final boolean directToField = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL ; final boolean directToField = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL ;
JetExpression r = getReceiverForSelector(expression); JetExpression r = getReceiverForSelector(expression);
final boolean isSuper = r instanceof JetSuperExpression; final boolean isSuper = r instanceof JetSuperExpression;
if (propertyDescriptor.getVisibility() == Visibilities.PRIVATE propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor);
&& !DescriptorUtils.isClassObject(propertyDescriptor.getContainingDeclaration())
&& propertyDescriptor.getContainingDeclaration() instanceof ClassDescriptor) {
if (context.getClassOrNamespaceDescriptor() != propertyDescriptor.getContainingDeclaration()) {
DeclarationDescriptor enclosed = propertyDescriptor.getContainingDeclaration();
if (enclosed != null && enclosed != context.getThisDescriptor()) {
CodegenContext c = context;
while(c.getContextDescriptor() != enclosed) {
c = c.getParentContext();
}
propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor);
}
}
}
final StackValue.Property iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null); final StackValue.Property iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null);
if (!directToField && resolvedCall != null && !isSuper) { if (!directToField && resolvedCall != null && !isSuper) {
receiver.put(propertyDescriptor.getReceiverParameter().exists() || isStatic receiver.put(propertyDescriptor.getReceiverParameter().exists() || isStatic
@@ -1235,13 +1222,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
boolean isInsideClass = !isFakeOverride && (((containingDeclaration == context.getThisDescriptor()) || boolean isInsideClass = !isFakeOverride && (((containingDeclaration == context.getThisDescriptor()) ||
(context.getParentContext() instanceof CodegenContexts.NamespaceContext) && context.getParentContext().getContextDescriptor() == containingDeclaration) (context.getParentContext() instanceof CodegenContexts.NamespaceContext) && context.getParentContext().getContextDescriptor() == containingDeclaration)
&& contextKind() != OwnerKind.TRAIT_IMPL); && contextKind() != OwnerKind.TRAIT_IMPL);
Method getter; Method getter = null;
Method setter; Method setter = null;
if (forceField) { if (!forceField) {
getter = null;
setter = null;
}
else {
//noinspection ConstantConditions //noinspection ConstantConditions
if (isInsideClass && (propertyDescriptor.getGetter() == null || propertyDescriptor.getGetter().isDefault() && propertyDescriptor.getGetter().getModality() == Modality.FINAL)) { if (isInsideClass && (propertyDescriptor.getGetter() == null || propertyDescriptor.getGetter().isDefault() && propertyDescriptor.getGetter().getModality() == Modality.FINAL)) {
getter = null; getter = null;
@@ -1261,6 +1244,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
} }
} }
} }
else {
propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor);
}
getter = typeMapper.mapGetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); getter = typeMapper.mapGetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
if (propertyDescriptor.getGetter() == null) { if (propertyDescriptor.getGetter() == null) {
@@ -1314,6 +1301,25 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return StackValue.property(propertyDescriptor.getName().getName(), owner, ownerParam, asmType(propertyDescriptor.getType()), isStatic, isInterface, isSuper, getter, setter, invokeOpcode); return StackValue.property(propertyDescriptor.getName().getName(), owner, ownerParam, asmType(propertyDescriptor.getType()), isStatic, isInterface, isSuper, getter, setter, invokeOpcode);
} }
private PropertyDescriptor accessablePropertyDescriptor(PropertyDescriptor propertyDescriptor) {
if ((propertyDescriptor.getVisibility() == Visibilities.PRIVATE ||(propertyDescriptor.getSetter() != null && propertyDescriptor.getSetter().getVisibility() == Visibilities.PRIVATE))
&& !DescriptorUtils.isClassObject(propertyDescriptor.getContainingDeclaration())
&& propertyDescriptor.getContainingDeclaration() instanceof ClassDescriptor) {
if (context.getClassOrNamespaceDescriptor() != propertyDescriptor.getContainingDeclaration()) {
DeclarationDescriptor enclosed = propertyDescriptor.getContainingDeclaration();
if (enclosed != context.getThisDescriptor()) {
CodegenContext c = context;
while(c != null && c.getContextDescriptor() != enclosed) {
c = c.getParentContext();
}
if(c != null)
propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor);
}
}
}
return propertyDescriptor;
}
static boolean isOverrideForTrait(CallableMemberDescriptor propertyDescriptor) { static boolean isOverrideForTrait(CallableMemberDescriptor propertyDescriptor) {
if (propertyDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { if (propertyDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
final Set<? extends CallableMemberDescriptor> overriddenDescriptors = propertyDescriptor.getOverriddenDescriptors(); final Set<? extends CallableMemberDescriptor> overriddenDescriptors = propertyDescriptor.getOverriddenDescriptors();
@@ -0,0 +1,14 @@
class P {
var x : Int = 0
private set
fun foo() {
({ x = 4 })()
}
}
fun box() : String {
val p = P()
p.foo()
return if (p.x == 4) "OK" else "fail"
}
@@ -227,6 +227,11 @@ public class PropertyGenTest extends CodegenTestCase {
blackBoxFile("regressions/kt1398.kt"); blackBoxFile("regressions/kt1398.kt");
} }
public void testKt2331() throws Exception {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxFile("regressions/kt2331.kt");
}
public void testKt1482_2279() throws Exception { public void testKt1482_2279() throws Exception {
createEnvironmentWithFullJdk(); createEnvironmentWithFullJdk();
blackBoxFile("regressions/kt1482_2279.kt"); blackBoxFile("regressions/kt1482_2279.kt");