KT-2331 fix: proper dealing with privite property setters
This commit is contained in:
@@ -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");
|
||||||
|
|||||||
Reference in New Issue
Block a user