From bcec8b7c364f3bbb7532d02e4d65947188fee89a Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Sat, 4 Aug 2012 08:10:38 +0300 Subject: [PATCH] KT-2331 fix: proper dealing with privite property setters --- .../jetbrains/jet/codegen/CodegenContext.java | 27 ++++++----- .../jet/codegen/ExpressionCodegen.java | 48 +++++++++++-------- .../testData/codegen/regressions/kt2331.kt | 14 ++++++ .../jet/codegen/PropertyGenTest.java | 5 ++ 4 files changed, 62 insertions(+), 32 deletions(-) create mode 100644 compiler/testData/codegen/regressions/kt2331.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java index 402cf9bce73..4f76c0d8c39 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java @@ -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.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.emptyList(), pd.getExpectedThisObject(), receiverType); PropertyGetterDescriptor pgd = new PropertyGetterDescriptor( - myAccessor, Collections.emptyList(), myAccessor.getModality(), - myAccessor.getVisibility(), + myAccessor, Collections.emptyList(), + Modality.FINAL, + Visibilities.PUBLIC, false, false, CallableMemberDescriptor.Kind.DECLARATION); pgd.initialize(myAccessor.getType()); PropertySetterDescriptor psd = new PropertySetterDescriptor( - myAccessor, Collections.emptyList(), myAccessor.getModality(), - myAccessor.getVisibility(), + myAccessor, Collections.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 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) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index e2a3198802d..48989f693f0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1062,20 +1062,7 @@ public class ExpressionCodegen extends JetVisitor { 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 { 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 { } } } + 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 { 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 overriddenDescriptors = propertyDescriptor.getOverriddenDescriptors(); diff --git a/compiler/testData/codegen/regressions/kt2331.kt b/compiler/testData/codegen/regressions/kt2331.kt new file mode 100644 index 00000000000..faa235985f5 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt2331.kt @@ -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" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java index 721fad29a49..a4884acb8d2 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PropertyGenTest.java @@ -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");