string concatenation

This commit is contained in:
Dmitry Jemerov
2011-04-14 20:42:51 +02:00
parent 8e551399a1
commit 0e492472b3
2 changed files with 36 additions and 2 deletions
@@ -22,6 +22,10 @@ import java.util.Stack;
* @author max
*/
public class ExpressionCodegen extends JetVisitor {
private static final String CLASS_OBJECT = "java/lang/Object";
private static final String CLASS_STRING = "java/lang/String";
private static final String CLASS_STRING_BUILDER = "java/lang/StringBuilder";
private final Stack<Label> myLoopStarts = new Stack<Label>();
private final Stack<Label> myLoopEnds = new Stack<Label>();
private final Stack<StackValue> myStack = new Stack<StackValue>();
@@ -341,7 +345,7 @@ public class ExpressionCodegen extends JetVisitor {
final JetDotQualifiedExpression parent = (JetDotQualifiedExpression) expression.getParent();
if (!resolvesToClassOrPackage(parent.getReceiverExpression())) {
// we have a receiver on stack
myStack.pop().put(Type.getObjectType("java/lang/Object"), v);
myStack.pop().put(Type.getObjectType(CLASS_OBJECT), v);
}
}
@@ -523,6 +527,10 @@ public class ExpressionCodegen extends JetVisitor {
}
return;
}
else if (isClass(cls, "String") && op.getName().equals("plus")) {
generateConcatenation(expression);
return;
}
}
throw new UnsupportedOperationException("Don't know how to generate binary op " + expression);
}
@@ -578,7 +586,7 @@ public class ExpressionCodegen extends JetVisitor {
v.ifnull(rightNull);
Label leftNull = new Label();
v.ifnull(leftNull);
v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
v.invokevirtual(CLASS_OBJECT, "equals", "(Ljava/lang/Object;)Z");
Label end = new Label();
v.goTo(end);
v.mark(rightNull);
@@ -702,6 +710,26 @@ public class ExpressionCodegen extends JetVisitor {
}
}
private void generateConcatenation(JetBinaryExpression expression) {
Type type = Type.getObjectType(CLASS_STRING_BUILDER);
v.anew(type);
v.dup();
Method method = new Method("<init>", Type.VOID_TYPE, new Type[0]);
v.invokespecial(CLASS_STRING_BUILDER, method.getName(), method.getDescriptor());
invokeAppend(expression.getLeft());
invokeAppend(expression.getRight());
v.invokevirtual(CLASS_STRING_BUILDER, "toString", "()Ljava/lang/String;");
myStack.push(StackValue.onStack(Type.getObjectType(CLASS_STRING)));
}
private void invokeAppend(final JetExpression expr) {
Type exprType = expressionType(expr);
gen(expr, exprType);
Method appendDescriptor = new Method("append", Type.getObjectType(CLASS_STRING_BUILDER),
new Type[] { exprType.getSort() == Type.OBJECT ? Type.getObjectType(CLASS_OBJECT) : exprType});
v.invokevirtual(CLASS_STRING_BUILDER, "append", appendDescriptor.getDescriptor());
}
@Override
public void visitPrefixExpression(JetPrefixExpression expression) {
DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationSign());
@@ -562,6 +562,12 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
assertEquals("foo", main.invoke(null));
}
public void testStringPlus() throws Exception {
loadText("fun foo(s1: String, s2: String) = s1 + s2");
final Method main = generateFunction();
assertEquals("jetLang", main.invoke(null, "jet", "Lang"));
}
private void binOpTest(final String text, final Object arg1, final Object arg2, final Object expected) throws Exception {
loadText(text);
System.out.println(generateToText());