From eba70a1e39e5e31837c8b3e378df1aee041d2740 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Sat, 24 Sep 2011 22:33:36 +0300 Subject: [PATCH] many bug fixes --- .../jetbrains/jet/codegen/ClassCodegen.java | 3 +- .../jetbrains/jet/codegen/CodegenUtil.java | 30 +++++++++++++++++++ .../jet/codegen/ConstructorFrameMap.java | 2 +- .../jet/codegen/ExpressionCodegen.java | 10 +++++-- .../codegen/ImplementationBodyCodegen.java | 4 +-- .../jetbrains/jet/codegen/JetTypeMapper.java | 5 ++-- idea/testData/codegen/traits/stdlib.jet | 17 ++++++++--- .../jetbrains/jet/codegen/TypeInfoTest.java | 1 + 8 files changed, 59 insertions(+), 13 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java index 1933acff885..0a13ef4158d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java @@ -21,9 +21,10 @@ public class ClassCodegen { public void generate(ClassContext parentContext, JetClassOrObject aClass) { GenerationState.prepareAnonymousClasses((JetElement) aClass, state.getTypeMapper()); + ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); + generateImplementation(parentContext, aClass, OwnerKind.IMPLEMENTATION); - ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); final ClassContext contextForInners = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION); for (JetDeclaration declaration : aClass.getDeclarations()) { if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index f388bcc53e0..205d116fda9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -24,4 +24,34 @@ public class CodegenUtil { public static boolean isInterface(JetType type) { return isInterface(type.getConstructor().getDeclarationDescriptor()); } + + public static boolean isClassObject(DeclarationDescriptor descriptor) { + if(descriptor instanceof ClassDescriptor) { + ClassDescriptor classDescriptor = (ClassDescriptor) descriptor; + if(classDescriptor.getKind() == ClassKind.OBJECT) { + if(classDescriptor.getContainingDeclaration() instanceof ClassDescriptor) { + ClassDescriptor containingDeclaration = (ClassDescriptor) classDescriptor.getContainingDeclaration(); + if(classDescriptor.getDefaultType().equals(containingDeclaration.getClassObjectType())) { + return true; + } + } + } + } + return false; + } + + public static boolean hasThis0(ClassDescriptor classDescriptor) { + return getOuterClassDescriptor(classDescriptor) != null && !isClassObject(classDescriptor); + } + + public static ClassDescriptor getOuterClassDescriptor(ClassDescriptor descriptor) { + DeclarationDescriptor outerDescriptor = descriptor.getContainingDeclaration(); + while(outerDescriptor != null) { + if(outerDescriptor instanceof ClassDescriptor) + break; + + outerDescriptor = outerDescriptor.getContainingDeclaration(); + } + return (ClassDescriptor) outerDescriptor; + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java b/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java index f1961e5ac18..f9be40b26c5 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java @@ -22,7 +22,7 @@ public class ConstructorFrameMap extends FrameMap { ClassDescriptor classDescriptor = null; if (descriptor != null) { classDescriptor = descriptor.getContainingDeclaration(); - if (classDescriptor.getContainingDeclaration() instanceof ClassDescriptor) { + if (CodegenUtil.hasThis0(classDescriptor)) { myOuterThisIndex = enterTemp(); // outer class instance } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index b5d9adb0dfe..057c135f583 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -550,7 +550,9 @@ public class ExpressionCodegen extends JetVisitor { Type type = Type.getObjectType(descriptor.getClassname()); v.anew(type); v.dup(); - v.invokespecial(descriptor.getClassname(), "", descriptor.getConstructor().getDescriptor()); + v.load(0, JetTypeMapper.TYPE_OBJECT); + String jvmDescriptor = descriptor.getConstructor().getDescriptor().replace("(","(" + typeMapper.jetImplementationType((ClassDescriptor) contextType())); + v.invokespecial(descriptor.getClassname(), "", jvmDescriptor); return StackValue.onStack(type); } @@ -905,6 +907,9 @@ public class ExpressionCodegen extends JetVisitor { if (declarationPsiElement instanceof PsiMethod || declarationPsiElement instanceof JetNamedFunction) { callableMethod = typeMapper.mapToCallableMethod((PsiNamedElement) declarationPsiElement, null); } + else if (fd instanceof VariableAsFunctionDescriptor) { + callableMethod = ClosureCodegen.asCallableMethod((FunctionDescriptor) fd); + } else if (fd instanceof FunctionDescriptor) { callableMethod = ClosureCodegen.asCallableMethod((FunctionDescriptor) fd); } @@ -940,7 +945,8 @@ public class ExpressionCodegen extends JetVisitor { } if (callableMethod.needsReceiverOnStack()) { if (receiver == StackValue.none()) { - receiver = thisExpression(); + ClassDescriptor receiverClass = callableMethod.getReceiverClass(); + receiver = receiverClass == null ? thisExpression() : generateThisOrOuter(receiverClass); } receiver.put(JetTypeMapper.TYPE_OBJECT, v); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index f3fdbb7b180..b73520b3c54 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -374,8 +374,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (myClass.getParent() instanceof JetClassObject) { return null; } - final DeclarationDescriptor outerDescriptor = descriptor.getContainingDeclaration(); - return outerDescriptor instanceof ClassDescriptor ? (ClassDescriptor) outerDescriptor : null; + + return CodegenUtil.getOuterClassDescriptor(descriptor); } private void generateDelegatorToConstructorCall(InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall, diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 6f4c07b316f..91ad14a4f3f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -568,9 +568,8 @@ public class JetTypeMapper { List parameters = descriptor.getOriginal().getValueParameters(); List parameterTypes = new ArrayList(); ClassDescriptor classDescriptor = descriptor.getContainingDeclaration(); - final DeclarationDescriptor outerDescriptor = classDescriptor.getContainingDeclaration(); - if (outerDescriptor instanceof ClassDescriptor && classDescriptor.getKind() != ClassKind.OBJECT) { - parameterTypes.add(jvmType((ClassDescriptor) outerDescriptor, OwnerKind.IMPLEMENTATION)); + if (CodegenUtil.hasThis0(classDescriptor)) { + parameterTypes.add(jvmType(CodegenUtil.getOuterClassDescriptor(classDescriptor), OwnerKind.IMPLEMENTATION)); } for (ValueParameterDescriptor parameter : parameters) { final Type type = mapType(parameter.getOutType()); diff --git a/idea/testData/codegen/traits/stdlib.jet b/idea/testData/codegen/traits/stdlib.jet index 7be1c38af9c..d5f91dc5205 100644 --- a/idea/testData/codegen/traits/stdlib.jet +++ b/idea/testData/codegen/traits/stdlib.jet @@ -2,17 +2,20 @@ trait ISized { val size : Int } -trait ReadOnlyArray : ISized, Iterable { +trait ReadOnlyArray : ISized, java.lang.Iterable { fun get(index : Int) : T - override fun iterator () : Iterator = object : Iterator { + class MyIterator() : java.util.Iterator { private var index = 0 override fun hasNext() : Boolean = index < size - val next : T - get() = get(index++) + override fun next() : T = get(index++) + + override fun remove () : Unit {} } + + override fun iterator() : java.util.Iterator = MyIterator() } trait WriteOnlyArray : ISized { @@ -40,5 +43,11 @@ fun box() : String { a [0] = 10 a.set(1, 2, 13) a [3] = 40 + System.out?.println(a.iterator()) + System.out?.println(a.iterator().hasNext()) +// if(a.iterator() !is Iterator) return "fail"; +// for(el in a) { +// System.out?.println(el) +// } return "OK" } \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/codegen/TypeInfoTest.java b/idea/tests/org/jetbrains/jet/codegen/TypeInfoTest.java index 39f2db4abfa..687d42cb60d 100644 --- a/idea/tests/org/jetbrains/jet/codegen/TypeInfoTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/TypeInfoTest.java @@ -113,6 +113,7 @@ public class TypeInfoTest extends CodegenTestCase { public void testClassObjectInTypeInfo() throws Exception { loadFile(); + System.out.println(generateToText()); Method foo = generateFunction(); JetObject jetObject = (JetObject) foo.invoke(null); TypeInfo typeInfo = jetObject.getTypeInfo();