diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/ConstructorInvocation.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/ConstructorInvocation.java index 9fd826b4d76..5ae70f17642 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/ConstructorInvocation.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/ConstructorInvocation.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.codegen.inline; +import org.jetbrains.annotations.NotNull; import org.jetbrains.org.objectweb.asm.Type; import java.util.List; @@ -25,6 +26,8 @@ public class ConstructorInvocation { private final String ownerInternalName; + private final String desc; + private final Map lambdasToInline; private final boolean isSameModule; @@ -37,15 +40,17 @@ public class ConstructorInvocation { private Map capturedLambdasToInline; - private boolean capturedOuterRegenerated; + private final boolean capturedOuterRegenerated; ConstructorInvocation( - String ownerInternalName, - Map lambdasToInline, + @NotNull String ownerInternalName, + @NotNull String desc, + @NotNull Map lambdasToInline, boolean isSameModule, boolean capturedOuterRegenerated ) { this.ownerInternalName = ownerInternalName; + this.desc = desc; this.lambdasToInline = lambdasToInline; this.isSameModule = isSameModule; this.capturedOuterRegenerated = capturedOuterRegenerated; @@ -95,4 +100,7 @@ public class ConstructorInvocation { this.capturedLambdasToInline = capturedLambdasToInline; } + public String getDesc() { + return desc; + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaTransformer.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaTransformer.java index 98350d56204..e96e8f298ba 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaTransformer.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/LambdaTransformer.java @@ -18,20 +18,22 @@ package org.jetbrains.jet.codegen.inline; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.OutputFile; -import org.jetbrains.jet.codegen.*; +import org.jetbrains.jet.codegen.AsmUtil; +import org.jetbrains.jet.codegen.ClassBuilder; +import org.jetbrains.jet.codegen.FieldInfo; +import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.org.objectweb.asm.*; -import org.jetbrains.org.objectweb.asm.commons.Method; +import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.tree.*; import java.io.IOException; import java.util.*; -import static org.jetbrains.org.objectweb.asm.Opcodes.V1_6; - public class LambdaTransformer { protected final GenerationState state; @@ -48,8 +50,6 @@ public class LambdaTransformer { private final ClassReader reader; - private String superName; - private final boolean isSameModule; private final Map> fieldNames = new HashMap>(); @@ -91,28 +91,13 @@ public class LambdaTransformer { @NotNull public InlineResult doTransform(@NotNull ConstructorInvocation invocation, @NotNull FieldRemapper parentRemapper) { - final ClassBuilder classBuilder = createClassBuilder(); + ClassBuilder classBuilder = createClassBuilder(); final List methodsToTransform = new ArrayList(); - final List fieldToAdd = new ArrayList(); reader.accept(new ClassVisitor(InlineCodegenUtil.API, classBuilder.getVisitor()) { - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - //TODO: public visibility for inline function - LambdaTransformer.this.superName = superName; - classBuilder.defineClass(null, - V1_6, - access, - newLambdaType.getInternalName(), - signature, - superName, - interfaces - ); - } - @Override public MethodVisitor visitMethod( - int access, String name, String desc, String signature, String[] exceptions + int access, @NotNull String name, @NotNull String desc, String signature, String[] exceptions ) { MethodNode node = new MethodNode(access, name, desc, signature, exceptions); if (name.equals("")){ @@ -128,26 +113,32 @@ public class LambdaTransformer { @Override public FieldVisitor visitField( - int access, String name, String desc, String signature, Object value + int access, @NotNull String name, @NotNull String desc, String signature, Object value ) { addUniqueField(name); - FieldNode fieldNode = new FieldNode(access, name, desc, signature, value); - fieldToAdd.add(fieldNode); - return fieldNode; + if (InlineCodegenUtil.isCapturedFieldName(name)) { + return null; + } else { + return super.visitField(access, name, desc, signature, value); + } } }, ClassReader.SKIP_FRAMES); - ParametersBuilder capturedBuilder = ParametersBuilder.newBuilder(); - extractParametersMappingAndPatchConstructor(constructor, capturedBuilder, invocation); + ParametersBuilder allCapturedParamBuilder = ParametersBuilder.newBuilder(); + ParametersBuilder constructorParamBuilder = ParametersBuilder.newBuilder(); + extractParametersMappingAndPatchConstructor(constructor, allCapturedParamBuilder, constructorParamBuilder, invocation); InlineResult result = InlineResult.create(); for (MethodNode next : methodsToTransform) { MethodVisitor visitor = newMethod(classBuilder, next); - InlineResult funResult = inlineMethod(invocation, parentRemapper, visitor, next, capturedBuilder); + InlineResult funResult = inlineMethod(invocation, parentRemapper, visitor, next, allCapturedParamBuilder); result.addAllClassesToRemove(funResult); } - generateConstructorAndFields(classBuilder, capturedBuilder, invocation); + InlineResult constructorResult = + generateConstructorAndFields(classBuilder, allCapturedParamBuilder, constructorParamBuilder, invocation, parentRemapper); + + result.addAllClassesToRemove(constructorResult); classBuilder.done(); @@ -178,22 +169,82 @@ public class LambdaTransformer { return result; } - private void generateConstructorAndFields(@NotNull ClassBuilder classBuilder, @NotNull ParametersBuilder builder, @NotNull ConstructorInvocation invocation) { - List infos = builder.buildCaptured(); - List> newConstructorSignature = new ArrayList>(); - for (CapturedParamInfo capturedParamInfo : infos) { - if (capturedParamInfo.getLambda() == null) { //not inlined - newConstructorSignature.add(new Pair(capturedParamInfo.getNewFieldName(), capturedParamInfo.getType())); + private InlineResult generateConstructorAndFields( + @NotNull ClassBuilder classBuilder, + @NotNull ParametersBuilder allCapturedBuilder, + @NotNull ParametersBuilder constructorInlineBuilder, + @NotNull ConstructorInvocation invocation, + @NotNull FieldRemapper parentRemapper + ) { + List descTypes = new ArrayList(); + + Parameters constructorParams = constructorInlineBuilder.buildParameters(); + final int [] capturedIndexes = new int [constructorParams.totalSize()]; + int index = 0; + int size = 0; + + //complex processing cause it could have super constructor call params + for (ParameterInfo info : constructorParams) { + if (!info.isSkipped()) { //not inlined + if (info.isCaptured() || info instanceof CapturedParamInfo) { + capturedIndexes[index] = size; + index++; + } + + if (size != 0) { //skip this + descTypes.add(info.getType()); + } + size += info.getType().getSize(); } } - List fields = AsmUtil.transformCapturedParams(newConstructorSignature, newLambdaType); + final List> capturedFieldsToGenerate = new ArrayList>(); + for (CapturedParamInfo capturedParamInfo : allCapturedBuilder.listCaptured()) { + if (capturedParamInfo.getLambda() == null) { //not inlined + capturedFieldsToGenerate.add(new Pair(capturedParamInfo.getNewFieldName(), capturedParamInfo.getType())); + } + } - AsmUtil.genClosureFields(newConstructorSignature, classBuilder); + String constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, descTypes.toArray(new Type[descTypes.size()])); + MethodVisitor constructorVisitor = classBuilder.newMethod(null, + AsmUtil.NO_FLAG_PACKAGE_PRIVATE, + "", constructorDescriptor, + null, ArrayUtil.EMPTY_STRING_ARRAY); + + MethodVisitor capturedFieldInitializer = new InstructionAdapter(InlineCodegenUtil.API, constructorVisitor) { + private boolean superCallProcessed; + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { + super.visitMethodInsn(opcode, owner, name, desc, itf); + if (!superCallProcessed && "".equals(name)) { + superCallProcessed = true; + List fields = AsmUtil.transformCapturedParams(capturedFieldsToGenerate, newLambdaType); + int paramIndex = 0; + for (FieldInfo fieldInfo : fields) { + AsmUtil.genAssignInstanceFieldFromParam(fieldInfo, capturedIndexes[paramIndex], this); + paramIndex++; + } + } + } + }; + + Parameters constructorParameters = constructorInlineBuilder.buildParameters(); + + RegeneratedLambdaFieldRemapper remapper = + new RegeneratedLambdaFieldRemapper(oldObjectType.getInternalName(), newLambdaType.getInternalName(), + constructorParameters, invocation.getCapturedLambdasToInline(), + parentRemapper); + + MethodInliner inliner = new MethodInliner(constructor, constructorParameters, inliningContext.subInline(inliningContext.nameGenerator.subGenerator("lambda")), + remapper, isSameModule, "Transformer for constructor of " + invocation.getOwnerInternalName()); + InlineResult result = inliner.doInline(capturedFieldInitializer, new LocalVarRemapper(constructorParameters, 0), false); + constructorVisitor.visitMaxs(-1, -1); + + AsmUtil.genClosureFields(capturedFieldsToGenerate, classBuilder); //TODO for inline method make public class - Method newConstructor = ClosureCodegen.generateConstructor(classBuilder, fields, null, Type.getObjectType(superName), state, AsmUtil.NO_FLAG_PACKAGE_PRIVATE); - invocation.setNewConstructorDescriptor(newConstructor.getDescriptor()); + invocation.setNewConstructorDescriptor(constructorDescriptor); + return result; } @NotNull @@ -203,7 +254,7 @@ public class LambdaTransformer { ) { ParametersBuilder builder = ParametersBuilder.newBuilder(); buildInvokeParamsFor(builder, sourceNode); - for (CapturedParamInfo param : capturedBuilder.getCapturedParams()) { + for (CapturedParamInfo param : capturedBuilder.listCaptured()) { builder.addCapturedParamCopy(param); } return builder.buildParameters(); @@ -229,11 +280,11 @@ public class LambdaTransformer { private void extractParametersMappingAndPatchConstructor( @NotNull MethodNode constructor, - @NotNull ParametersBuilder builder, + @NotNull ParametersBuilder capturedParamBuilder, + @NotNull ParametersBuilder constructorParamBuilder, @NotNull final ConstructorInvocation invocation ) { - Map indexToLambda = invocation.getLambdasToInline(); - List capturedLambdas = new ArrayList(); //captured var of inlined parameter + CapturedParamOwner owner = new CapturedParamOwner() { @Override public Type getType() { @@ -241,24 +292,41 @@ public class LambdaTransformer { } }; - AbstractInsnNode cur = constructor.instructions.getFirst(); - //load captured parameters (NB: there is also could be object fields) - while (cur != null) { - if (cur instanceof FieldInsnNode && cur.getOpcode() == Opcodes.PUTFIELD && InlineCodegenUtil.isCapturedFieldName(((FieldInsnNode) cur).name)) { - FieldInsnNode fieldNode = (FieldInsnNode) cur; - CapturedParamInfo info = builder.addCapturedParam(owner, fieldNode.name, Type.getType(fieldNode.desc), false, null); + List capturedLambdas = new ArrayList(); //captured var of inlined parameter + List capturedToInline = new ArrayList(); + Map indexToLambda = invocation.getLambdasToInline(); + Set capturedParams = new HashSet(); - boolean isPrevVarNode = fieldNode.getPrevious() instanceof VarInsnNode; - boolean isPrevPrevVarNode = isPrevVarNode && fieldNode.getPrevious().getPrevious() instanceof VarInsnNode; - if (isPrevPrevVarNode) { - VarInsnNode node = (VarInsnNode) fieldNode.getPrevious().getPrevious(); - if (node.var == 0) { - VarInsnNode previous = (VarInsnNode) fieldNode.getPrevious(); - int varIndex = previous.var; - LambdaInfo lambdaInfo = indexToLambda.get(varIndex); - if (lambdaInfo != null) { - info.setLambda(lambdaInfo); - capturedLambdas.add(lambdaInfo); + //load captured parameters and patch instruction list (NB: there is also could be object fields) + AbstractInsnNode cur = constructor.instructions.getFirst(); + while (cur != null) { + if (cur instanceof FieldInsnNode) { + FieldInsnNode fieldNode = (FieldInsnNode) cur; + if (fieldNode.getOpcode() == Opcodes.PUTFIELD && InlineCodegenUtil.isCapturedFieldName(fieldNode.name)) { + + boolean isPrevVarNode = fieldNode.getPrevious() instanceof VarInsnNode; + boolean isPrevPrevVarNode = isPrevVarNode && fieldNode.getPrevious().getPrevious() instanceof VarInsnNode; + + if (isPrevPrevVarNode) { + VarInsnNode node = (VarInsnNode) fieldNode.getPrevious().getPrevious(); + if (node.var == 0) { + VarInsnNode previous = (VarInsnNode) fieldNode.getPrevious(); + int varIndex = previous.var; + LambdaInfo lambdaInfo = indexToLambda.get(varIndex); + CapturedParamInfo info = capturedParamBuilder.addCapturedParam(owner, fieldNode.name, Type.getType(fieldNode.desc), lambdaInfo != null, null); + if (lambdaInfo != null) { + info.setLambda(lambdaInfo); + capturedLambdas.add(lambdaInfo); + capturedToInline.add(info); + } + capturedParams.add(varIndex); + + constructor.instructions.remove(previous.getPrevious()); + constructor.instructions.remove(previous); + AbstractInsnNode temp = cur; + cur = cur.getNext(); + constructor.instructions.remove(temp); + continue; } } } @@ -266,13 +334,27 @@ public class LambdaTransformer { cur = cur.getNext(); } + constructorParamBuilder.addThis(oldObjectType, false); + Type [] types = Type.getArgumentTypes(invocation.getDesc()); + for (Type type : types) { + LambdaInfo info = indexToLambda.get(constructorParamBuilder.getNextValueParameterIndex()); + ParameterInfo parameterInfo = constructorParamBuilder.addNextParameter(type, info != null, null); + parameterInfo.setLambda(info); + if (capturedParams.contains(parameterInfo.getIndex())) { + parameterInfo.setCaptured(true); + } else { + //otherwise it's super constructor parameter + } + } + //For all inlined lambdas add their captured parameters //TODO: some of such parameters could be skipped - we should perform additional analysis Map capturedLambdasToInline = new HashMap(); //captured var of inlined parameter List allRecapturedParameters = new ArrayList(); for (LambdaInfo info : capturedLambdas) { for (CapturedParamInfo var : info.getCapturedVars()) { - CapturedParamInfo recapturedParamInfo = builder.addCapturedParam(var, getNewFieldName(var.getOriginalFieldName())); + CapturedParamInfo recapturedParamInfo = capturedParamBuilder.addCapturedParam(var, + getNewFieldName(var.getOriginalFieldName())); StackValue composed = StackValue.composed(StackValue.local(0, oldObjectType), StackValue.field(var.getType(), oldObjectType, /*TODO owner type*/ @@ -280,10 +362,18 @@ public class LambdaTransformer { ); recapturedParamInfo.setRemapValue(composed); allRecapturedParameters.add(var); + + constructorParamBuilder.addCapturedParam(var, recapturedParamInfo.getNewFieldName()).setRemapValue(composed); } capturedLambdasToInline.put(info.getLambdaClassType().getInternalName(), info); } + //HACK: in inlinining into constructor we access inlined lambda with field access not local var but this lambda added no general params not captured one, + //so we need to add them to captured params + for (CapturedParamInfo info : capturedToInline) { + constructorParamBuilder.addCapturedParamCopy(info); + } + invocation.setAllRecapturedParameters(allRecapturedParameters); invocation.setCapturedLambdasToInline(capturedLambdasToInline); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/MethodInliner.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/MethodInliner.java index 58fc13a99c3..a8870b58a21 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/MethodInliner.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/MethodInliner.java @@ -352,7 +352,7 @@ public class MethodInliner { } } - constructorInvocations.add(new ConstructorInvocation(owner, lambdaMapping, isSameModule, inliningContext.classRegeneration)); + constructorInvocations.add(new ConstructorInvocation(owner, desc, lambdaMapping, isSameModule, inliningContext.classRegeneration)); } } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/ParameterInfo.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/ParameterInfo.java index 7940cb39400..159f7b89d49 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/ParameterInfo.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/ParameterInfo.java @@ -28,6 +28,8 @@ class ParameterInfo { protected final int index; + private boolean isCaptured; + public final Type type; //for skipped parameter: e.g. inlined lambda @@ -87,4 +89,12 @@ class ParameterInfo { public void setRemapValue(StackValue remapValue) { this.remapValue = remapValue; } + + public boolean isCaptured() { + return isCaptured; + } + + public void setCaptured(boolean isCaptured) { + this.isCaptured = isCaptured; + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/Parameters.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/Parameters.java index 6631f0cca94..d9097718f63 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/Parameters.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/Parameters.java @@ -88,10 +88,10 @@ public class Parameters implements Iterable { ArrayList result = new ArrayList(); for (CapturedParamInfo info : captured) { if(info != CapturedParamInfo.STUB) { - Type type = info.getType(); - result.add(type); + result.add(info.getType()); } } return result; } + } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/ParametersBuilder.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/ParametersBuilder.java index ef5b57ece72..954c9641c00 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/ParametersBuilder.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/ParametersBuilder.java @@ -43,9 +43,8 @@ public class ParametersBuilder { } @NotNull - public ParametersBuilder addNextParameter(@NotNull Type type, boolean skipped, @Nullable ParameterInfo original) { - addParameter(new ParameterInfo(type, skipped, nextIndex, original != null ? original.getIndex() : -1)); - return this; + public ParameterInfo addNextParameter(@NotNull Type type, boolean skipped, @Nullable ParameterInfo original) { + return addParameter(new ParameterInfo(type, skipped, nextIndex, original != null ? original.getIndex() : -1)); } @NotNull @@ -83,9 +82,10 @@ public class ParametersBuilder { return addCapturedParameter(info); } - private void addParameter(ParameterInfo info) { + private ParameterInfo addParameter(ParameterInfo info) { params.add(info); nextIndex += info.getType().getSize(); + return info; } private CapturedParamInfo addCapturedParameter(CapturedParamInfo info) { @@ -94,27 +94,30 @@ public class ParametersBuilder { return info; } - public List build() { + @NotNull + public List listNotCaptured() { return Collections.unmodifiableList(params); } - public List buildCaptured() { + @NotNull + public List listCaptured() { return Collections.unmodifiableList(capturedParams); } - public List buildWithStubs() { - return Parameters.addStubs(build()); + @NotNull + private List buildWithStubs() { + return Parameters.addStubs(listNotCaptured()); } - public List buildCapturedWithStubs() { - return Parameters.shiftAndAddStubs(buildCaptured(), nextIndex); + private List buildCapturedWithStubs() { + return Parameters.shiftAndAddStubs(listCaptured(), nextIndex); } public Parameters buildParameters() { return new Parameters(buildWithStubs(), buildCapturedWithStubs()); } - public List getCapturedParams() { - return capturedParams; + public int getNextValueParameterIndex() { + return nextIndex; } } diff --git a/compiler/testData/codegen/boxInline/anonymousObjectSuperParams/1.kt b/compiler/testData/codegen/boxInline/anonymousObjectOnCallSiteSuperParams/1.kt similarity index 100% rename from compiler/testData/codegen/boxInline/anonymousObjectSuperParams/1.kt rename to compiler/testData/codegen/boxInline/anonymousObjectOnCallSiteSuperParams/1.kt diff --git a/compiler/testData/codegen/boxInline/anonymousObjectSuperParams/2.kt b/compiler/testData/codegen/boxInline/anonymousObjectOnCallSiteSuperParams/2.kt similarity index 100% rename from compiler/testData/codegen/boxInline/anonymousObjectSuperParams/2.kt rename to compiler/testData/codegen/boxInline/anonymousObjectOnCallSiteSuperParams/2.kt diff --git a/compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSite/1.kt b/compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSite/1.kt new file mode 100644 index 00000000000..901a56aaab4 --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSite/1.kt @@ -0,0 +1,30 @@ +import test.* + +fun test1(): String { + val o = "O" + + val result = doWork ({o}, {"K"}) + + return result.getO() + result.getK() +} + +fun test2() : String { + //same names as in object + val o1 = "O" + val k1 = "K" + + val result = doWorkInConstructor ({o1}, {k1}) + + return result.getO() + result.getK() +} + +fun box() : String { + val result1 = test1(); + if (result1 != "OK") return "fail1 $result1" + + val result2 = test2(); + if (result2 != "OK") return "fail2 $result2" + + return "OK" +} + diff --git a/compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSite/2.kt b/compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSite/2.kt new file mode 100644 index 00000000000..ea41a21fac8 --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSite/2.kt @@ -0,0 +1,36 @@ +package test + +abstract class A { + abstract fun getO() : R + + abstract fun getK() : R +} + +inline fun doWork(jobO: ()-> R, jobK: ()-> R) : A { + val s = object : A() { + + override fun getO(): R { + return jobO() + } + override fun getK(): R { + return jobK() + } + } + return s; +} + +inline fun doWorkInConstructor(jobO: ()-> R, jobK: ()-> R) : A { + val s = object : A() { + val o1 = jobO() + + val k1 = jobK() + + override fun getO(): R { + return o1 + } + override fun getK(): R { + return k1 + } + } + return s; +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSiteSuperParams/1.kt b/compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSiteSuperParams/1.kt new file mode 100644 index 00000000000..64eb69081f7 --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSiteSuperParams/1.kt @@ -0,0 +1,30 @@ +import test.* + +fun test1(): String { + val o = "O" + + val result = doWork ({o}, {"K"}, "11") + + return result.getO() + result.getK() + result.param +} + +fun test2() : String { + //same names as in object + val o1 = "O" + val k1 = "K" + val param = "11" + val result = doWorkInConstructor ({o1}, {k1}, {param}) + + return result.getO() + result.getK() + result.param +} + +fun box() : String { + val result1 = test1(); + if (result1 != "OK11") return "fail1 $result1" + + val result2 = test2(); + if (result2 != "OK11") return "fail2 $result2" + + return "OK" +} + diff --git a/compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSiteSuperParams/2.kt b/compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSiteSuperParams/2.kt new file mode 100644 index 00000000000..5c7af7ad686 --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSiteSuperParams/2.kt @@ -0,0 +1,36 @@ +package test + +abstract class A(val param : R) { + abstract fun getO() : R + + abstract fun getK() : R +} + +inline fun doWork(jobO: ()-> R, jobK: ()-> R, param: R) : A { + val s = object : A(param) { + + override fun getO(): R { + return jobO() + } + override fun getK(): R { + return jobK() + } + } + return s; +} + +inline fun doWorkInConstructor(jobO: ()-> R, jobK: ()-> R, param: () -> R) : A { + val s = object : A(param()) { + val o1 = jobO() + + val k1 = jobK() + + override fun getO(): R { + return o1 + } + override fun getK(): R { + return k1 + } + } + return s; +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxInlineCodegenTestGenerated.java index 0d42e145e1d..738e2ebecb7 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxInlineCodegenTestGenerated.java @@ -41,9 +41,19 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxCodegenT doTestMultiFileWithInlineCheck("compiler/testData/codegen/boxInline/anonymousObjectOnCallSite"); } - @TestMetadata("anonymousObjectSuperParams") - public void testAnonymousObjectSuperParams() throws Exception { - doTestMultiFileWithInlineCheck("compiler/testData/codegen/boxInline/anonymousObjectSuperParams"); + @TestMetadata("anonymousObjectOnCallSiteSuperParams") + public void testAnonymousObjectOnCallSiteSuperParams() throws Exception { + doTestMultiFileWithInlineCheck("compiler/testData/codegen/boxInline/anonymousObjectOnCallSiteSuperParams"); + } + + @TestMetadata("anonymousObjectOnDeclarationSite") + public void testAnonymousObjectOnDeclarationSite() throws Exception { + doTestMultiFileWithInlineCheck("compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSite"); + } + + @TestMetadata("anonymousObjectOnDeclarationSiteSuperParams") + public void testAnonymousObjectOnDeclarationSiteSuperParams() throws Exception { + doTestMultiFileWithInlineCheck("compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSiteSuperParams"); } @TestMetadata("builders") diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstInlineKotlinTestGenerated.java index 39adac7a05a..1a2b7552d42 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -41,9 +41,19 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi doBoxTestWithInlineCheck("compiler/testData/codegen/boxInline/anonymousObjectOnCallSite"); } - @TestMetadata("anonymousObjectSuperParams") - public void testAnonymousObjectSuperParams() throws Exception { - doBoxTestWithInlineCheck("compiler/testData/codegen/boxInline/anonymousObjectSuperParams"); + @TestMetadata("anonymousObjectOnCallSiteSuperParams") + public void testAnonymousObjectOnCallSiteSuperParams() throws Exception { + doBoxTestWithInlineCheck("compiler/testData/codegen/boxInline/anonymousObjectOnCallSiteSuperParams"); + } + + @TestMetadata("anonymousObjectOnDeclarationSite") + public void testAnonymousObjectOnDeclarationSite() throws Exception { + doBoxTestWithInlineCheck("compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSite"); + } + + @TestMetadata("anonymousObjectOnDeclarationSiteSuperParams") + public void testAnonymousObjectOnDeclarationSiteSuperParams() throws Exception { + doBoxTestWithInlineCheck("compiler/testData/codegen/boxInline/anonymousObjectOnDeclarationSiteSuperParams"); } @TestMetadata("builders")