diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index bf5e985cfeb..d36204d73cc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -793,7 +793,7 @@ public class ExpressionCodegen extends JetVisitor { } if(closureCodegen.superCall != null) { - ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) closureCodegen.superCall).getCalleeExpression().getConstructorReferenceExpression()); + ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, closureCodegen.superCall.getCalleeExpression().getConstructorReferenceExpression()); CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION); Type[] argumentTypes = superCallable.getSignature().getAsmMethod().getArgumentTypes(); Collections.addAll(consArgTypes, argumentTypes); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 0bcdd1b958f..a75901720c5 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -385,7 +385,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JvmMethodSignature constructorMethod; CallableMethod callableMethod; if (constructorDescriptor == null) { - BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false); signatureWriter.writeFormalTypeParametersStart(); @@ -417,10 +416,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ObjectOrClosureCodegen closure = context.closure; int firstSuperArgument = -1; - if(closure != null) { - final LinkedList consArgTypes = new LinkedList(constructorMethod.getKotlinParameterTypes()); + final LinkedList consArgTypes = new LinkedList(constructorMethod.getKotlinParameterTypes()); - int insert = 0; + int insert = 0; + if(closure != null) { if(closure.captureThis) { if(!CodegenUtil.hasThis0(descriptor)) consArgTypes.add(insert, new JvmMethodParameterSignature(Type.getObjectType(context.getThisDescriptor().getName()), "", JvmMethodParameterKind.THIS0)); @@ -444,22 +443,27 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { assert closure.captureReceiver != null; } } + } - if(myClass instanceof JetObjectDeclaration) { - if(superCall instanceof JetDelegatorToSuperCall) { + if(myClass instanceof JetObjectDeclaration && ((JetObjectDeclaration) myClass).isObjectLiteral()) { + if(superCall instanceof JetDelegatorToSuperCall) { + if(closure != null) closure.superCall = (JetDelegatorToSuperCall) superCall; - ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); - CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION); - firstSuperArgument = insert; - for(Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) { - consArgTypes.add(insert++, new JvmMethodParameterSignature(t, "", JvmMethodParameterKind.SHARED_VAR)); - } + DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); + if(declarationDescriptor instanceof ClassDescriptor) { + declarationDescriptor = ((ClassDescriptor)declarationDescriptor).getUnsubstitutedPrimaryConstructor(); + } + ConstructorDescriptor superConstructor = (ConstructorDescriptor) declarationDescriptor; + CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION); + firstSuperArgument = insert; + for(Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) { + consArgTypes.add(insert++, new JvmMethodParameterSignature(t, "", JvmMethodParameterKind.SHARED_VAR)); } } - - constructorMethod = JvmMethodSignature.simple("", Type.VOID_TYPE, consArgTypes); } + constructorMethod = JvmMethodSignature.simple("", Type.VOID_TYPE, consArgTypes); + int flags = ACC_PUBLIC; // TODO final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(), constructorMethod.getGenericsSignature(), null); if (!v.generateCode()) return; @@ -547,7 +551,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "", superCallMethod.getDescriptor()); } else { - iv.load(0, classType); ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap, firstSuperArgument); } @@ -726,17 +729,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ConstructorDescriptor constructorDescriptor, ConstructorFrameMap frameMap, int firstSuperArgument) { ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration(); - Type type = typeMapper.mapType(classDecl.getDefaultType(), OwnerKind.IMPLEMENTATION); - iv.load(0, type); + iv.load(0, TYPE_OBJECT); if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) { iv.load(frameMap.getOuterThisIndex(), typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), OwnerKind.IMPLEMENTATION)); } CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, kind); - if(myClass instanceof JetObjectDeclaration && superCall instanceof JetDelegatorToSuperCall) { - iv.load(0, TYPE_OBJECT); + + if(myClass instanceof JetObjectDeclaration && superCall instanceof JetDelegatorToSuperCall && ((JetObjectDeclaration) myClass).isObjectLiteral()) { ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION); int nextVar = firstSuperArgument+1; diff --git a/compiler/testData/codegen/regressions/kt1213.kt b/compiler/testData/codegen/regressions/kt1213.kt new file mode 100644 index 00000000000..da860c37840 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt1213.kt @@ -0,0 +1,11 @@ +package interactive; + +class Shape(var height : Double = 1.0, var fillColor : String = "#AAAAAA") { + +} + +fun box() : String { + var a : Shape? = Shape() + a?.height = 1.0 + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java index cbe06a10c81..849049d71bf 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -265,4 +265,8 @@ public class ClassGenTest extends CodegenTestCase { public void testKt471() throws Exception { blackBoxFile("regressions/kt471.kt"); } + + public void testKt1213() throws Exception { +// blackBoxFile("regressions/kt1213.kt"); + } } diff --git a/examples/src/actors/actors.iws b/examples/src/actors/actors.iws index 989317a4ff9..fac93df883a 100644 --- a/examples/src/actors/actors.iws +++ b/examples/src/actors/actors.iws @@ -61,7 +61,7 @@ - + @@ -100,12 +100,16 @@ - - + + - - @@ -144,16 +148,12 @@ - - + + - - - - @@ -161,17 +161,17 @@ - - + - + + - - + + @@ -228,6 +228,24 @@ + + + - - - - + @@ -357,7 +357,7 @@ - + @@ -426,7 +426,7 @@ - + diff --git a/testlib/test/regressions/kt1202.kt b/testlib/test/regressions/kt1202.kt new file mode 100644 index 00000000000..e158681e0ac --- /dev/null +++ b/testlib/test/regressions/kt1202.kt @@ -0,0 +1,119 @@ +package testeval + +import java.util.* +import junit.framework.TestCase.* + +trait Expression +class Num(val value : Int) : Expression +class Sum(val left : Expression, val right : Expression) : Expression +class Mult(val left : Expression, val right : Expression) : Expression + +fun eval(e : Expression) : Int { + return when (e) { + is Num -> e.value + is Sum -> eval(e.left) + eval (e.right) + is Mult -> eval(e.left) * eval (e.right) + else -> throw AssertionError("Unknown expression") + } +} + +trait ParseResult { + val success : Boolean + val value : T +} + +class Success(override val value : T) : ParseResult { + public override val success : Boolean = true +} + +class Failure(val message : String) : ParseResult { + override val success = false + override val value : Nothing = throw UnsupportedOperationException("Don't call value on a Failure") +} + +open class Token(val text : String) { + fun toString() = text +} +object LPAR : Token("(") +object RPAR : Token(")") +object PLUS : Token("+") +object TIMES : Token("*") +object EOF : Token("EOF") +class Number(text : String) : Token(text) +class Error(text : String) : Token("[Error: $text]") + + +fun tokenize(text : String) : Deque { + val result = LinkedList() + for (c in text) { + result add when (c) { + '(' -> LPAR + ')' -> RPAR + '+' -> PLUS + '*' -> TIMES + in '0'..'9' -> Number(c.toString()) + else -> Error(c.toString()) + } + } + result.add(EOF) + return result +} + +fun parseSum(tokens : Deque) : ParseResult { + val left = parseMult(tokens) + if (!left.success) return left + + if (tokens.peek() == PLUS) { + tokens.pop() + val right = parseSum(tokens) + if (!right.success) return right + return Success(Sum(left.value, right.value)) + } + + return left +} + +fun parseMult(tokens : Deque) : ParseResult { + val left = parseAtomic(tokens) + if (!left.success) return left + + if (tokens.peek() == PLUS) { + tokens.pop() + val right = parseMult(tokens) + if (!right.success) return right + return Success(Mult(left.value, right.value)) + } + + return left +} + +fun parseAtomic(tokens : Deque) : ParseResult { + val token = tokens.poll() + return when (token) { + LPAR -> { + val result = parseSum(tokens) + val rpar = tokens.poll() + if (rpar == RPAR) + result + else + Failure("Expecting ')'") + } + is Number -> Success(Num(Integer.parseInt((token as Token).text).sure())) + else -> Failure("Unexpected EOF") + } +} + +fun parse(text : String) : ParseResult = parseSum(tokenize(text)) + +class EvalTest : junit.framework.TestCase() { + fun testEval() { + assertEquals(1, eval(Num(1))) + assertEquals(2, eval(Sum(Num(1), Num(1)))) + assertEquals(3, eval(Mult(Num(3), Num(1)))) + assertEquals(6, eval(Mult(Num(3), Sum(Num(1), Num(1))))) + } + + fun testParse() { + assertEquals(1, eval(parse("1").value)) + } +}