KT-508 accessors for enclosed private fields

This commit is contained in:
Alex Tkachman
2011-11-14 19:34:00 +02:00
parent cf3217cdc1
commit 3b2fb0da8f
6 changed files with 59 additions and 8 deletions
@@ -28,6 +28,9 @@ public class ClassCodegen {
if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) {
generate(contextForInners, (JetClass) declaration);
}
if(declaration instanceof JetClassObject) {
state.forClass().generate(contextForInners, ((JetClassObject)declaration).getObjectDeclaration());
}
}
generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors);
@@ -47,6 +47,19 @@ public abstract class CodegenContext {
}
protected abstract ClassDescriptor getThisDescriptor ();
public DeclarationDescriptor getClassOrNamespaceDescriptor() {
CodegenContext c = this;
while(true) {
DeclarationDescriptor contextDescriptor = c.getContextDescriptor();
if(!(contextDescriptor instanceof ClassDescriptor) && !(contextDescriptor instanceof NamespaceDescriptor)) {
c = c.getParentContext();
}
else {
return contextDescriptor;
}
}
}
protected CallableDescriptor getReceiverDescriptor() {
return null;
@@ -797,7 +797,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
}
else if (descriptor instanceof PropertyDescriptor) {
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
//TODO: hack, will not need if resolve goes to right descriptor itself
if (declaration instanceof JetParameter) {
@@ -828,6 +828,16 @@ 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() == Visibility.PRIVATE && 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 iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null);
if(!directToField && resolvedCall != null && !isSuper) {
if (resolvedCall.getThisObject().exists()) {
@@ -218,7 +218,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv = new InstructionAdapter(mv);
iv.load(0, JetTypeMapper.TYPE_OBJECT);
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
if(original.getVisibility() == Visibility.PRIVATE)
iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), original.getName(), originalMethod.getReturnType().getDescriptor());
else
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
iv.areturn(method.getReturnType());
mv.visitMaxs(0,0);
@@ -241,7 +244,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
//noinspection AssignmentToForLoopParameter
reg += argType.getSize();
}
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
if(original.getVisibility() == Visibility.PRIVATE)
iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), original.getName(), originalMethod.getArgumentTypes()[0].getDescriptor());
else
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
iv.areturn(method.getReturnType());
mv.visitMaxs(0,0);
@@ -572,7 +578,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateSecondaryConstructor((JetSecondaryConstructor) declaration);
}
else if (declaration instanceof JetClassObject) {
generateClassObject((JetClassObject) declaration);
// done earlier in order to have accessors
}
else if (declaration instanceof JetEnumEntry && !((JetEnumEntry) declaration).hasPrimaryConstructor()) {
String name = declaration.getName();
@@ -874,8 +880,4 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
});
}
private void generateClassObject(JetClassObject declaration) {
state.forClass().generate(context, declaration.getObjectDeclaration());
}
}
@@ -0,0 +1,17 @@
namespace mult_constructors_3_bug
public open class Identifier() {
private var myNullable : Boolean = true
class object {
open public fun init(isNullable : Boolean) : Identifier {
val __ = Identifier()
__.myNullable = isNullable
return __
}
}
}
fun box() : String {
Identifier.init(true)
return "OK"
}
@@ -196,4 +196,10 @@ public class ClassGenTest extends CodegenTestCase {
System.out.println(generateToText());
blackBox();
}
public void testKt508 () throws Exception {
loadFile("regressions/kt508.jet");
System.out.println(generateToText());
blackBox();
}
}