diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.kt index dd323410f21..9880aad0ef8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.kt @@ -32,20 +32,19 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter class Concat : IntrinsicMethod() { fun generateImpl( - codegen: ExpressionCodegen, - v: InstructionAdapter, - returnType: Type, - element: PsiElement?, - arguments: List, - receiver: StackValue + codegen: ExpressionCodegen, + v: InstructionAdapter, + returnType: Type, + element: PsiElement?, + arguments: List, + receiver: StackValue ): Type { if (element is KtBinaryExpression && element.operationReference.getReferencedNameElementType() == KtTokens.PLUS) { // LHS + RHS genStringBuilderConstructor(v) codegen.invokeAppend(v, element.left) codegen.invokeAppend(v, element.right) - } - else { + } else { // Explicit plus call LHS?.plus(RHS) or LHS.plus(RHS) receiver.put(AsmTypes.JAVA_STRING_TYPE, v) genStringBuilderConstructor(v) @@ -59,41 +58,41 @@ class Concat : IntrinsicMethod() { } override fun toCallable(method: CallableMethod): Callable = - object : IntrinsicCallable(method) { - override fun invokeMethodWithArguments( - resolvedCall: ResolvedCall<*>, - receiver: StackValue, - codegen: ExpressionCodegen - ): StackValue { - if (resolvedCall.call.callElement.parent is KtCallableReferenceExpression) { - // NB we come here only in case of inlined callable reference to String::plus. - // This will map arguments properly, invoking callbacks defined in Callable. - return super.invokeMethodWithArguments(resolvedCall, receiver, codegen) - } - return StackValue.operation(returnType) { - val arguments = resolvedCall.call.valueArguments.map { it.getArgumentExpression()!! } - val actualType = generateImpl( - codegen, it, returnType, - resolvedCall.call.callElement, - arguments, - StackValue.receiver(resolvedCall, receiver, codegen, this) - ) - StackValue.coerce(actualType, returnType, it) - } + object : IntrinsicCallable(method) { + override fun invokeMethodWithArguments( + resolvedCall: ResolvedCall<*>, + receiver: StackValue, + codegen: ExpressionCodegen + ): StackValue { + if (resolvedCall.call.callElement.parent is KtCallableReferenceExpression) { + // NB we come here only in case of inlined callable reference to String::plus. + // This will map arguments properly, invoking callbacks defined in Callable. + return super.invokeMethodWithArguments(resolvedCall, receiver, codegen) } - - override fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap) { - v.generateNewInstanceDupAndPlaceBeforeStackTop(frameMap, AsmTypes.JAVA_STRING_TYPE, "java/lang/StringBuilder") - v.invokespecial("java/lang/StringBuilder", "", "(Ljava/lang/String;)V", false) - } - - override fun invokeIntrinsic(v: InstructionAdapter) { - // String::plus has type String.(Any?) -> String, thus we have no argument type information - // in case of callable reference passed to a generic function, e.g.: - // charArrayOf('O', 'K').fold("", String::plus) - // TODO Make String::plus generic, and invoke proper StringBuilder#append. - genInvokeAppendMethod(v, AsmTypes.OBJECT_TYPE, null) - v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false) + return StackValue.operation(returnType) { + val arguments = resolvedCall.call.valueArguments.map { it.getArgumentExpression()!! } + val actualType = generateImpl( + codegen, it, returnType, + resolvedCall.call.callElement, + arguments, + StackValue.receiver(resolvedCall, receiver, codegen, this) + ) + StackValue.coerce(actualType, returnType, it) } } + + override fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap) { + v.generateNewInstanceDupAndPlaceBeforeStackTop(frameMap, AsmTypes.JAVA_STRING_TYPE, "java/lang/StringBuilder") + v.invokespecial("java/lang/StringBuilder", "", "(Ljava/lang/String;)V", false) + } + + override fun invokeIntrinsic(v: InstructionAdapter) { + // String::plus has type String.(Any?) -> String, thus we have no argument type information + // in case of callable reference passed to a generic function, e.g.: + // charArrayOf('O', 'K').fold("", String::plus) + // TODO Make String::plus generic, and invoke proper StringBuilder#append. + genInvokeAppendMethod(v, AsmTypes.OBJECT_TYPE, null) + v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false) + } + } }