From 538aa869b4c5a35dc64f33439ee590fb27594384 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Mon, 24 Dec 2012 14:33:54 +0400 Subject: [PATCH] Constructor with default arguments for inner class #KT-2852 Fixed --- .../jet/codegen/FunctionCodegen.java | 24 +++++-- .../blackBox/constructor/defArgs1.kt | 8 +++ .../constructor/defArgs1InnerClass.kt | 14 ++++ .../blackBox/constructor/defArgs2.kt | 13 ++++ .../blackBox/constructor/kt2852.kt | 7 ++ ...DefaultArgumentsBlackBoxTestGenerated.java | 71 +++++++++++++++++++ .../jet/generators/tests/GenerateTests.java | 14 ++++ 7 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs1.kt create mode 100644 compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs1InnerClass.kt create mode 100644 compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs2.kt create mode 100644 compiler/testData/codegen/defaultArguments/blackBox/constructor/kt2852.kt create mode 100644 compiler/tests/org/jetbrains/jet/codegen/generated/DefaultArgumentsBlackBoxTestGenerated.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 271065c15cf..95b1df3b943 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -551,6 +551,9 @@ public class FunctionCodegen extends GenerationStateAware { ReceiverParameterDescriptor receiverParameter = functionDescriptor.getReceiverParameter(); boolean hasReceiver = receiverParameter != null; + // TODO change this condition when nested classes will be implemented + // Has outer in local variables (constructor for inner class) + boolean hasOuter = functionDescriptor instanceof ConstructorDescriptor && functionDescriptor.getExpectedThisObject() != null; boolean isStatic = isStatic(kind); if (kind == OwnerKind.TRAIT_IMPL) { @@ -583,7 +586,7 @@ public class FunctionCodegen extends GenerationStateAware { genStubCode(mv); } else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { - generateDefaultImpl(owner, state, jvmSignature, functionDescriptor, kind, receiverParameter, hasReceiver, isStatic, + generateDefaultImpl(owner, state, jvmSignature, functionDescriptor, kind, receiverParameter, hasReceiver, hasOuter, isStatic, ownerInternalName, isConstructor, mv, iv, loadStrategy); } @@ -596,7 +599,7 @@ public class FunctionCodegen extends GenerationStateAware { FunctionDescriptor functionDescriptor, OwnerKind kind, ReceiverParameterDescriptor receiverParameter, - boolean hasReceiver, + boolean hasReceiver, boolean hasOuter, boolean aStatic, JvmClassName ownerInternalName, boolean constructor, @@ -612,6 +615,10 @@ public class FunctionCodegen extends GenerationStateAware { frameMap.leaveTemp(OBJECT_TYPE); } + if (hasOuter) { + frameMap.enterTemp(OBJECT_TYPE); + } + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), owner, state); int var = 0; @@ -619,6 +626,10 @@ public class FunctionCodegen extends GenerationStateAware { var++; } + if (hasOuter) { + var++; + } + Type receiverType; if (hasReceiver) { receiverType = state.getTypeMapper().mapType(receiverParameter.getType()); @@ -631,7 +642,7 @@ public class FunctionCodegen extends GenerationStateAware { Type[] argTypes = jvmSignature.getArgumentTypes(); List paramDescrs = functionDescriptor.getValueParameters(); for (int i = 0; i < paramDescrs.size(); i++) { - Type argType = argTypes[i + (hasReceiver ? 1 : 0)]; + Type argType = argTypes[i + ((hasReceiver || hasOuter) ? 1 : 0)]; int size = argType.getSize(); frameMap.enter(paramDescrs.get(i), argType); var += size; @@ -644,12 +655,17 @@ public class FunctionCodegen extends GenerationStateAware { mv.visitVarInsn(ALOAD, var++); } + if (hasOuter) { + iv.load(var, ownerInternalName.getAsmType()); + var++; + } + if (hasReceiver) { iv.load(var, receiverType); var += receiverType.getSize(); } - int extra = hasReceiver ? 1 : 0; + int extra = (hasReceiver || hasOuter) ? 1 : 0; for (int index = 0; index < paramDescrs.size(); index++) { ValueParameterDescriptor parameterDescriptor = paramDescrs.get(index); diff --git a/compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs1.kt b/compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs1.kt new file mode 100644 index 00000000000..db8161f1911 --- /dev/null +++ b/compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs1.kt @@ -0,0 +1,8 @@ +class A(val a: Int = 0) + +fun box(): String { + if (A().a == 0 && A(1).a == 1) { + return "OK" + } + return "fail" +} diff --git a/compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs1InnerClass.kt b/compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs1InnerClass.kt new file mode 100644 index 00000000000..eabbda234bf --- /dev/null +++ b/compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs1InnerClass.kt @@ -0,0 +1,14 @@ +class A { + class B(val a: String = "a", val b: Int = 55, val c: String = "c") +} + +fun box(): String { + val bDefault = A().B() + val b = A().B("aa", 66, "cc") + if (bDefault.a == "a" && bDefault.b == 55 && bDefault.c == "c") { + if (b.a == "aa" && b.b == 66 && b.c == "cc") { + return "OK" + } + } + return "fail" +} diff --git a/compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs2.kt b/compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs2.kt new file mode 100644 index 00000000000..9a22d318336 --- /dev/null +++ b/compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs2.kt @@ -0,0 +1,13 @@ +class A(val a: Int = 0, val b: String = "a") + +fun box(): String { + val a1 = A() + val a2 = A(1) + val a3 = A(b = "b") + val a4 = A(2, "c") + if (a1.a != 0 && a1.b != "a") return "fail" + if (a2.a != 1 && a2.b != "a") return "fail" + if (a3.a != 0 && a3.b != "b") return "fail" + if (a4.a != 2 && a4.b != "c") return "fail" + return "OK" +} diff --git a/compiler/testData/codegen/defaultArguments/blackBox/constructor/kt2852.kt b/compiler/testData/codegen/defaultArguments/blackBox/constructor/kt2852.kt new file mode 100644 index 00000000000..34f2d616092 --- /dev/null +++ b/compiler/testData/codegen/defaultArguments/blackBox/constructor/kt2852.kt @@ -0,0 +1,7 @@ +fun box(): String { + val o = object { + class A(val value: String = "OK") + } + + return o.A().value +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/DefaultArgumentsBlackBoxTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/DefaultArgumentsBlackBoxTestGenerated.java new file mode 100644 index 00000000000..dfde2cfcb1e --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/DefaultArgumentsBlackBoxTestGenerated.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.jet.codegen.generated; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.codegen.generated.AbstractCodegenTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ +@TestMetadata("compiler/testData/codegen/defaultArguments/blackBox") +@InnerTestClasses({DefaultArgumentsBlackBoxTestGenerated.Constructor.class}) +public class DefaultArgumentsBlackBoxTestGenerated extends AbstractCodegenTest { + public void testAllFilesPresentInBlackBox() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/defaultArguments/blackBox"), "kt", true); + } + + @TestMetadata("compiler/testData/codegen/defaultArguments/blackBox/constructor") + public static class Constructor extends AbstractCodegenTest { + public void testAllFilesPresentInConstructor() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/defaultArguments/blackBox/constructor"), "kt", true); + } + + @TestMetadata("defArgs1.kt") + public void testDefArgs1() throws Exception { + doTest("compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs1.kt"); + } + + @TestMetadata("defArgs1InnerClass.kt") + public void testDefArgs1InnerClass() throws Exception { + doTest("compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs1InnerClass.kt"); + } + + @TestMetadata("defArgs2.kt") + public void testDefArgs2() throws Exception { + doTest("compiler/testData/codegen/defaultArguments/blackBox/constructor/defArgs2.kt"); + } + + @TestMetadata("kt2852.kt") + public void testKt2852() throws Exception { + doTest("compiler/testData/codegen/defaultArguments/blackBox/constructor/kt2852.kt"); + } + + } + + public static Test suite() { + TestSuite suite = new TestSuite("DefaultArgumentsBlackBoxTestGenerated"); + suite.addTestSuite(DefaultArgumentsBlackBoxTestGenerated.class); + suite.addTestSuite(Constructor.class); + return suite; + } +} diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 85201c22e39..725580257b9 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -101,6 +101,20 @@ public class GenerateTests { testModel("compiler/testData/writeFlags") ); + generateTest( + "compiler/tests/", + "DefaultArgumentsBlackBoxTestGenerated", + AbstractCodegenTest.class, + testModel("compiler/testData/codegen/defaultArguments/blackBox") + ); + + generateTest( + "compiler/tests/", + "DefaultArgumentsBlackBoxTestGenerated", + AbstractCodegenTest.class, + testModel("compiler/testData/codegen/defaultArguments/blackBox") + ); + generateTest( "compiler/tests/", "LabelGenTestGenerated",