diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index aa635e82674..fc0e692da05 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -2809,7 +2809,16 @@ public class ExpressionCodegen extends JetVisitor implem JetType initializerType = bindingContext.get(EXPRESSION_TYPE, initializer); assert initializerType != null; - final ExpressionReceiver initializerAsReceiver = new ExpressionReceiver(initializer, initializerType); + + final Type initializerAsmType = asmType(initializerType); + + final TransientReceiver initializerAsReceiver = new TransientReceiver(initializerType); + + final int tempVarIndex = myFrameMap.enterTemp(initializerAsmType); + + gen(initializer, initializerAsmType); + v.store(tempVarIndex, initializerAsmType); + final StackValue.Local local = StackValue.local(tempVarIndex, initializerAsmType); for (final JetMultiDeclarationEntry variableDeclaration : multiDeclaration.getEntries()) { initializeLocalVariable(variableDeclaration, new Function() { @@ -2819,11 +2828,18 @@ public class ExpressionCodegen extends JetVisitor implem bindingContext.get(BindingContext.COMPONENT_RESOLVED_CALL, variableDeclaration); assert resolvedCall != null : "Resolved call is null for " + variableDeclaration.getText(); Call call = makeFakeCall(initializerAsReceiver); - invokeFunction(call, StackValue.none(), resolvedCall); + invokeFunction(call, local, resolvedCall); return null; } }); } + + if(initializerAsmType.getSort() == Type.OBJECT || initializerAsmType.getSort() == Type.ARRAY) { + v.aconst(null); + v.store(tempVarIndex, initializerAsmType); + } + myFrameMap.leaveTemp(initializerAsmType); + return StackValue.none(); } diff --git a/compiler/testData/codegen/multiDecl/component.kt b/compiler/testData/codegen/multiDecl/component.kt new file mode 100644 index 00000000000..ec5b515705b --- /dev/null +++ b/compiler/testData/codegen/multiDecl/component.kt @@ -0,0 +1,17 @@ +class S(val a: String, val b: String) { + fun component1() : String = a + fun component2() : String = b +} + +fun S.component3() = ((a + b) as java.lang.String).substring(2) + +class Tester() { + fun box() : String { + val (o,k,ok,ok2) = S("O","K") + return o + k + ok + ok2 + } + + fun S.component4() = ((a + b) as java.lang.String).substring(2) +} + +fun box() = Tester().box() \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/ComponentGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ComponentGenTest.java new file mode 100644 index 00000000000..5d28c249c48 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/codegen/ComponentGenTest.java @@ -0,0 +1,37 @@ +/* + * 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; + +import org.jetbrains.jet.ConfigurationKind; + +/** + * This test is separate from MultiDeclTestGenerated because we specifically test generated bytecode + * that expression does not evaluated several time + */ +public class ComponentGenTest extends CodegenTestCase { + public void testComponent() { + createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY); + blackBoxFile("/multiDecl/component.kt"); + + String asm = generateToText(); + //System.out.println(asm); + final String pattern = "NEW S\n"; + final int index = asm.indexOf(pattern); + asm = asm.substring(index + pattern.length()); + assertEquals(-1, asm.indexOf(pattern)); + } +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/MultiDeclTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/MultiDeclTestGenerated.java index abf07ddd53f..a6dfb6f1534 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/MultiDeclTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/MultiDeclTestGenerated.java @@ -13,17 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.jetbrains.jet.codegen; -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.TestMetadata; -import org.jetbrains.jet.codegen.AbstractMultiDeclTestCase; +import java.io.File; /** This class is generated by {@link org.jetbrains.jet.codegen.AbstractMultiDeclTestCase}. DO NOT MODIFY MANUALLY */ @TestMetadata("compiler/testData/codegen/multiDecl") @@ -37,6 +35,11 @@ public class MultiDeclTestGenerated extends AbstractMultiDeclTestCase { blackBoxFileByFullPath("compiler/testData/codegen/multiDecl/ComplexInitializer.kt"); } + @TestMetadata("component.kt") + public void testComponent() throws Exception { + blackBoxFileByFullPath("compiler/testData/codegen/multiDecl/component.kt"); + } + @TestMetadata("SimpleVals.kt") public void testSimpleVals() throws Exception { blackBoxFileByFullPath("compiler/testData/codegen/multiDecl/SimpleVals.kt");