fix KT-249/KT-255

This commit is contained in:
Alex Tkachman
2011-09-03 22:52:12 +02:00
parent 07b2ab347d
commit 9ba167ee8d
5 changed files with 67 additions and 20 deletions
@@ -851,7 +851,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
DeclarationDescriptor funDescriptor = resolveCalleeDescriptor(expression);
if (funDescriptor instanceof ConstructorDescriptor) {
return generateConstructorCall(expression, (JetSimpleNameExpression) callee);
return generateConstructorCall(expression, (JetSimpleNameExpression) callee, receiver);
}
else if (funDescriptor instanceof FunctionDescriptor) {
final FunctionDescriptor fd = (FunctionDescriptor) funDescriptor;
@@ -1471,7 +1471,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return StackValue.none();
}
private StackValue generateConstructorCall(JetCallExpression expression, JetSimpleNameExpression constructorReference) {
private StackValue generateConstructorCall(JetCallExpression expression, JetSimpleNameExpression constructorReference, StackValue receiver) {
DeclarationDescriptor constructorDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, constructorReference);
final PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, constructorDescriptor);
Type type;
@@ -1486,11 +1486,26 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
else {
ClassDescriptor classDecl = (ClassDescriptor) constructorDescriptor.getContainingDeclaration();
receiver.put(receiver.type, v);
v.anew(type);
v.dup();
// TODO typechecker must verify that we're the outer class of the instance being created
pushOuterClassArguments(classDecl);
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
if(!receiver.type.equals(Type.VOID_TYPE)) {
// class object is in receiver
v.dupX1();
v.swap();
}
else {
// this$0 need to be put on stack
v.dup();
v.load(0, JetTypeMapper.jetImplementationType(classDecl));
}
}
else {
// regular case
v.dup();
}
CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION);
invokeMethodWithArguments(method, expression);
@@ -1513,12 +1528,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
generateTypeInfo(typeArgument);
}
private void pushOuterClassArguments(ClassDescriptor classDecl) {
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
v.load(0, JetTypeMapper.jetImplementationType(classDecl));
}
}
private Type generateJavaConstructorCall(JetCallExpression expression, PsiMethod constructor) {
PsiClass javaClass = constructor.getContainingClass();
Type type = JetTypeMapper.psiClassType(javaClass);
@@ -147,7 +147,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
protected void generatePrimaryConstructor() {
ConstructorDescriptor constructorDescriptor = state.getBindingContext().get(BindingContext.CONSTRUCTOR, (JetElement) myClass);
ConstructorDescriptor constructorDescriptor = state.getBindingContext().get(BindingContext.CONSTRUCTOR, myClass);
if (constructorDescriptor == null && !(myClass instanceof JetObjectDeclaration) && !isEnum(myClass)) return;
Method method;
@@ -193,10 +193,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.invokespecial(superClass, "<init>", /* TODO super constructor descriptor */"()V");
}
final DeclarationDescriptor outerDescriptor = getOuterClassDescriptor();
if (outerDescriptor instanceof ClassDescriptor) {
final ClassDescriptor outerClassDescriptor = (ClassDescriptor) outerDescriptor;
final Type type = JetTypeMapper.jetImplementationType(outerClassDescriptor);
final ClassDescriptor outerDescriptor = getOuterClassDescriptor();
if (outerDescriptor != null && !outerDescriptor.isObject()) {
final Type type = JetTypeMapper.jetImplementationType(outerDescriptor);
String interfaceDesc = type.getDescriptor();
final String fieldName = "this$0";
v.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, interfaceDesc, null, null);
@@ -216,7 +215,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
HashSet<FunctionDescriptor> overridden = new HashSet<FunctionDescriptor>();
for (JetDeclaration declaration : myClass.getDeclarations()) {
if (declaration instanceof JetFunction) {
overridden.addAll(state.getBindingContext().get(BindingContext.FUNCTION, (JetNamedFunction) declaration).getOverriddenFunctions());
overridden.addAll(state.getBindingContext().get(BindingContext.FUNCTION, declaration).getOverriddenFunctions());
}
}
@@ -410,8 +409,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
protected void generateInitializers(ExpressionCodegen codegen, InstructionAdapter iv) {
for (JetDeclaration declaration : myClass.getDeclarations()) {
if (declaration instanceof JetProperty) {
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, (JetProperty) declaration);
if ((boolean) state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration);
if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
final JetExpression initializer = ((JetProperty) declaration).getInitializer();
if (initializer != null) {
iv.load(0, JetTypeMapper.TYPE_OBJECT);
@@ -436,7 +435,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
propertyCodegen.gen((JetProperty) declaration);
}
else if (declaration instanceof JetFunction) {
if (!overriden.contains(state.getBindingContext().get(BindingContext.FUNCTION, (JetNamedFunction) declaration))) {
if (!overriden.contains(state.getBindingContext().get(BindingContext.FUNCTION, declaration))) {
functionCodegen.gen((JetNamedFunction) declaration);
}
}
@@ -22,7 +22,7 @@ public class JetObjectDeclaration extends JetNamedDeclaration implements JetClas
@Override
public String getName() {
JetObjectDeclarationName nameAsDeclaration = getNameAsDeclaration();
return nameAsDeclaration == null ? "<Anonymous>" : nameAsDeclaration.getName();
return nameAsDeclaration == null ? "ClassObj" : nameAsDeclaration.getName();
}
@Override
@@ -0,0 +1,35 @@
namespace x
class Outer(val name: String) {
class Inner() {
val me = name
class object {
fun bar() = "bar"
}
}
class object {
class StaticInner() {
class object {
fun f() = "oo"
}
}
}
}
fun box (): String {
val inner = Outer("mama").Inner() //verify error
if(inner.me != "mama")
return "fail"
val outer = Outer ("papa")
val inner2 = outer.Inner ()
if(inner2.me != "papa")
return "fail"
if(Outer.StaticInner.f() != "oo" )
return "fail"
return "OK"
}
@@ -168,4 +168,8 @@ public class ClassGenTest extends CodegenTestCase {
final Method rgbMethod = colorClass.getMethod("getRgb");
assertEquals(0xFF0000, rgbMethod.invoke(redValue));
}
public void testKt249() throws Exception {
blackBoxFile("regressions/kt249.jet");
}
}