KT-508 accessors for enclosed private fields
This commit is contained in:
@@ -28,6 +28,9 @@ public class ClassCodegen {
|
|||||||
if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) {
|
if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) {
|
||||||
generate(contextForInners, (JetClass) declaration);
|
generate(contextForInners, (JetClass) declaration);
|
||||||
}
|
}
|
||||||
|
if(declaration instanceof JetClassObject) {
|
||||||
|
state.forClass().generate(contextForInners, ((JetClassObject)declaration).getObjectDeclaration());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors);
|
generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors);
|
||||||
|
|||||||
@@ -47,6 +47,19 @@ public abstract class CodegenContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected abstract ClassDescriptor getThisDescriptor ();
|
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() {
|
protected CallableDescriptor getReceiverDescriptor() {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -797,7 +797,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (descriptor instanceof PropertyDescriptor) {
|
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
|
//TODO: hack, will not need if resolve goes to right descriptor itself
|
||||||
if (declaration instanceof JetParameter) {
|
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 ;
|
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() == 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);
|
final StackValue iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null);
|
||||||
if(!directToField && resolvedCall != null && !isSuper) {
|
if(!directToField && resolvedCall != null && !isSuper) {
|
||||||
if (resolvedCall.getThisObject().exists()) {
|
if (resolvedCall.getThisObject().exists()) {
|
||||||
|
|||||||
@@ -218,7 +218,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv = new InstructionAdapter(mv);
|
iv = new InstructionAdapter(mv);
|
||||||
|
|
||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
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());
|
iv.areturn(method.getReturnType());
|
||||||
mv.visitMaxs(0,0);
|
mv.visitMaxs(0,0);
|
||||||
@@ -241,7 +244,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
//noinspection AssignmentToForLoopParameter
|
//noinspection AssignmentToForLoopParameter
|
||||||
reg += argType.getSize();
|
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());
|
iv.areturn(method.getReturnType());
|
||||||
mv.visitMaxs(0,0);
|
mv.visitMaxs(0,0);
|
||||||
@@ -572,7 +578,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
generateSecondaryConstructor((JetSecondaryConstructor) declaration);
|
generateSecondaryConstructor((JetSecondaryConstructor) declaration);
|
||||||
}
|
}
|
||||||
else if (declaration instanceof JetClassObject) {
|
else if (declaration instanceof JetClassObject) {
|
||||||
generateClassObject((JetClassObject) declaration);
|
// done earlier in order to have accessors
|
||||||
}
|
}
|
||||||
else if (declaration instanceof JetEnumEntry && !((JetEnumEntry) declaration).hasPrimaryConstructor()) {
|
else if (declaration instanceof JetEnumEntry && !((JetEnumEntry) declaration).hasPrimaryConstructor()) {
|
||||||
String name = declaration.getName();
|
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());
|
System.out.println(generateToText());
|
||||||
blackBox();
|
blackBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKt508 () throws Exception {
|
||||||
|
loadFile("regressions/kt508.jet");
|
||||||
|
System.out.println(generateToText());
|
||||||
|
blackBox();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user