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.getValueParameters(),
fd.getReturnType(),
fd.getModality(),
fd.getVisibility(),
Modality.FINAL,
Visibilities.PUBLIC,
/*isInline = */ false);
accessor = myAccessor;
}
@@ -202,8 +202,8 @@ public abstract class CodegenContext {
PropertyDescriptor pd = (PropertyDescriptor) descriptor;
PropertyDescriptor myAccessor = new PropertyDescriptor(contextDescriptor,
Collections.<AnnotationDescriptor>emptyList(),
pd.getModality(),
pd.getVisibility(),
Modality.FINAL,
Visibilities.PUBLIC,
pd.isVar(),
pd.isObjectDeclaration(),
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);
PropertyGetterDescriptor pgd = new PropertyGetterDescriptor(
myAccessor, Collections.<AnnotationDescriptor>emptyList(), myAccessor.getModality(),
myAccessor.getVisibility(),
myAccessor, Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
Visibilities.PUBLIC,
false, false, CallableMemberDescriptor.Kind.DECLARATION);
pgd.initialize(myAccessor.getType());
PropertySetterDescriptor psd = new PropertySetterDescriptor(
myAccessor, Collections.<AnnotationDescriptor>emptyList(), myAccessor.getModality(),
myAccessor.getVisibility(),
myAccessor, Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
Visibilities.PUBLIC,
false, false, CallableMemberDescriptor.Kind.DECLARATION);
myAccessor.initialize(pgd, psd);
accessor = myAccessor;
}
@@ -235,10 +238,11 @@ public abstract class CodegenContext {
private int getHierarchyCount() {
ClassDescriptor descriptor = getThisDescriptor();
int c = 0;
while(true) {
while(descriptor != null) {
Collection<? extends JetType> supertypes = descriptor.getDefaultType().getConstructor().getSupertypes();
if (supertypes.isEmpty())
return c;
if (supertypes.isEmpty()) {
break;
}
c++;
for (JetType supertype : supertypes) {
descriptor = (ClassDescriptor) supertype.getConstructor().getDeclarationDescriptor();
@@ -247,6 +251,7 @@ public abstract class CodegenContext {
}
}
}
return c;
}
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 ;
JetExpression r = getReceiverForSelector(expression);
final boolean isSuper = r instanceof JetSuperExpression;
if (propertyDescriptor.getVisibility() == Visibilities.PRIVATE
&& !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);
}
}
}
propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor);
final StackValue.Property iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null);
if (!directToField && resolvedCall != null && !isSuper) {
receiver.put(propertyDescriptor.getReceiverParameter().exists() || isStatic
@@ -1235,13 +1222,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
boolean isInsideClass = !isFakeOverride && (((containingDeclaration == context.getThisDescriptor()) ||
(context.getParentContext() instanceof CodegenContexts.NamespaceContext) && context.getParentContext().getContextDescriptor() == containingDeclaration)
&& contextKind() != OwnerKind.TRAIT_IMPL);
Method getter;
Method setter;
if (forceField) {
getter = null;
setter = null;
}
else {
Method getter = null;
Method setter = null;
if (!forceField) {
//noinspection ConstantConditions
if (isInsideClass && (propertyDescriptor.getGetter() == null || propertyDescriptor.getGetter().isDefault() && propertyDescriptor.getGetter().getModality() == Modality.FINAL)) {
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();
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);
}
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) {
if (propertyDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
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");
}
public void testKt2331() throws Exception {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
blackBoxFile("regressions/kt2331.kt");
}
public void testKt1482_2279() throws Exception {
createEnvironmentWithFullJdk();
blackBoxFile("regressions/kt1482_2279.kt");