From 390c03d03fef07e348d71ad0bbdbf3851ab20591 Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Sat, 4 Apr 2015 10:46:59 +0300 Subject: [PATCH] Concat conversion --- .../kotlin/codegen/ExpressionCodegen.java | 47 ++-------- .../kotlin/codegen/intrinsics/Concat.kt | 90 +++++++++++-------- 2 files changed, 61 insertions(+), 76 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 13bb894ac1a..ffafbd05ff0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -2255,19 +2255,7 @@ public class ExpressionCodegen extends JetVisitor implem Callable callable = resolveToCallable(accessibleFunctionDescriptor, superCall, resolvedCall); Type returnType = typeMapper.mapReturnType(accessibleFunctionDescriptor); - if (callable instanceof ExtendedCallable) { - return ((ExtendedCallable) callable).invokeMethodWithArguments(resolvedCall, receiver, returnType, this); - } - else { - StackValue newReceiver = StackValue.receiver(resolvedCall, receiver, this, null); - - List args = new ArrayList(); - for (ValueArgument argument : call.getValueArguments()) { - args.add(argument.getArgumentExpression()); - } - - return ((IntrinsicMethod) callable).generate(this, returnType, call.getCallElement(), args, newReceiver); - } + return ((ExtendedCallable) callable).invokeMethodWithArguments(resolvedCall, receiver, returnType, this); } public void invokeMethodWithArguments( @@ -3020,13 +3008,6 @@ public class ExpressionCodegen extends JetVisitor implem return generateConstructorCall(resolvedCall, expressionType(expression)); } - Callable callable = resolveToCallable(descriptor, false, resolvedCall); - if (callable instanceof IntrinsicMethod) { - Type returnType = typeMapper.mapType(descriptor); - return ((IntrinsicMethod) callable).generate(this, returnType, expression, - Arrays.asList(expression.getLeft(), expression.getRight()), receiver); - } - return invokeFunction(resolvedCall, receiver); } } @@ -3298,26 +3279,8 @@ public class ExpressionCodegen extends JetVisitor implem JetExpression lhs = expression.getLeft(); Type lhsType = expressionType(lhs); - boolean keepReturnValue; - if (Boolean.TRUE.equals(bindingContext.get(VARIABLE_REASSIGNMENT, expression))) { - if (callable instanceof IntrinsicMethod) { - StackValue value = gen(lhs); // receiver - value = StackValue.complexWriteReadReceiver(value); - - value.put(lhsType, v); // receiver lhs - Type returnType = typeMapper.mapType(descriptor); - StackValue rightSide = ((IntrinsicMethod) callable).generate(this, returnType, expression, - Collections.singletonList(expression.getRight()), StackValue.onStack(lhsType)); - value.store(rightSide, v, true); - return StackValue.none(); - } - else { - keepReturnValue = true; - } - } - else { - keepReturnValue = !KotlinBuiltIns.getInstance().getUnitType().equals(descriptor.getReturnType()); - } + boolean keepReturnValue = Boolean.TRUE.equals(bindingContext.get(VARIABLE_REASSIGNMENT, expression)) + || !KotlinBuiltIns.getInstance().getUnitType().equals(descriptor.getReturnType()); callAugAssignMethod(expression, resolvedCall, (ExtendedCallable) callable, lhsType, keepReturnValue); @@ -3339,7 +3302,9 @@ public class ExpressionCodegen extends JetVisitor implem value.put(lhsType, v); StackValue receiver = StackValue.onStack(lhsType); - invokeMethodWithArguments(callable, resolvedCall, receiver); + //invokeMethodWithArguments(callable, resolvedCall, receiver); + + callable.invokeMethodWithArguments(resolvedCall, receiver, callable.getReturnType(), this).put(callable.getReturnType(), v); if (keepReturnValue) { value.store(StackValue.onStack(callable.getReturnType()), v, true); 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 26d0d0f5bec..ce4758e8a53 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.kt @@ -14,50 +14,70 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +package org.jetbrains.kotlin.codegen.intrinsics -import com.intellij.psi.PsiElement; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.codegen.ExpressionCodegen; -import org.jetbrains.kotlin.codegen.StackValue; -import org.jetbrains.kotlin.psi.JetExpression; -import org.jetbrains.kotlin.resolve.jvm.AsmTypes; -import org.jetbrains.org.objectweb.asm.Type; -import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; +import com.intellij.openapi.util.Key +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.psi.JetExpression +import org.jetbrains.kotlin.resolve.jvm.AsmTypes +import org.jetbrains.org.objectweb.asm.Type +import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter -import java.util.List; +import org.jetbrains.kotlin.codegen.AsmUtil.genInvokeAppendMethod +import org.jetbrains.kotlin.codegen.AsmUtil.genStringBuilderConstructor +import org.jetbrains.kotlin.codegen.ExtendedCallable +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.lexer.JetTokens +import org.jetbrains.kotlin.psi.JetBinaryExpression +import org.jetbrains.kotlin.psi.JetFile +import org.jetbrains.kotlin.psi.UserDataProperty +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE +import kotlin.properties.Delegates -import static org.jetbrains.kotlin.codegen.AsmUtil.genInvokeAppendMethod; -import static org.jetbrains.kotlin.codegen.AsmUtil.genStringBuilderConstructor; -import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE; +public class Concat : IntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List, receiver: StackValue): Type { -public class Concat extends IntrinsicMethod { - @NotNull - @Override - public Type generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull InstructionAdapter v, - @NotNull Type returnType, - PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - if (receiver == StackValue.none()) { + if (element is JetBinaryExpression && element.getOperationReference().getReferencedNameElementType() == JetTokens.PLUS) { // LHS + RHS - genStringBuilderConstructor(v); - codegen.invokeAppend(arguments.get(0)); - codegen.invokeAppend(arguments.get(1)); + genStringBuilderConstructor(v) + codegen.invokeAppend(element.getLeft()) + codegen.invokeAppend(element.getRight()) } else { // LHS?.plus(RHS) - receiver.put(AsmTypes.OBJECT_TYPE, v); - genStringBuilderConstructor(v); - v.swap(); - genInvokeAppendMethod(v, returnType); - codegen.invokeAppend(arguments.get(0)); + receiver.put(AsmTypes.OBJECT_TYPE, v) + genStringBuilderConstructor(v) + v.swap() + genInvokeAppendMethod(v, returnType) + codegen.invokeAppend(arguments.get(0)) } - v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); - return JAVA_STRING_TYPE; + v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false) + return JAVA_STRING_TYPE + } + + override fun supportCallable(): Boolean { + return true + } + + override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): ExtendedCallable { + val callable = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext()) + return object : MappedCallable(callable, {}) { + override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue { + return StackValue.operation(returnType) { + val arguments = resolvedCall.getCall().getValueArguments().map { it.getArgumentExpression() } + val actualType = generateImpl( + codegen, it, returnType, + resolvedCall.getCall().getCallElement(), + arguments, + StackValue.receiver(resolvedCall, receiver, codegen, this) + ) + StackValue.coerce(actualType, returnType, it) + } + } + } } }