string concatenation
This commit is contained in:
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user