提交 da6b4a95 编写于 作者: D Dmitry Jemerov

+= for strings

上级 bca39bf2
......@@ -828,25 +828,44 @@ public class ExpressionCodegen extends JetVisitor {
private void generateAugmentedAssignment(JetBinaryExpression expression) {
DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationReference());
final JetExpression lhs = expression.getLeft();
Type asmType = expressionType(lhs);
StackValue value = generateIntermediateValue(lhs);
value.dupReceiver(v);
value.put(asmType, v);
genToJVMStack(expression.getRight());
v.visitInsn(asmType.getOpcode(opcodeForMethod(op.getName())));
value.store(v);
Type lhsType = expressionType(lhs);
if (isNumberPrimitive(lhsType)) {
StackValue value = generateIntermediateValue(lhs); // receiver
value.dupReceiver(v, 0); // receiver receiver
value.put(lhsType, v); // receiver lhs
genToJVMStack(expression.getRight()); // receiver lhs rhs
v.visitInsn(lhsType.getOpcode(opcodeForMethod(op.getName()))); // receiver result
value.store(v);
}
else if ("java.lang.String".equals(lhsType.getClassName()) && op.getName().equals("plus")) {
generateStringBuilderConstructor(); // StringBuilder
StackValue value = generateIntermediateValue(lhs); // StringBuilder receiver
value.dupReceiver(v, 1); // receiver StringBuilder receiver
value.put(lhsType, v); // receiver StringBuilder value
invokeAppendMethod(lhsType); // receiver StringBuilder
invokeAppend(expression.getRight()); // receiver StringBuilder
v.invokevirtual(CLASS_STRING_BUILDER, "toString", "()Ljava/lang/String;");
value.store(v);
}
else {
throw new UnsupportedOperationException("Augmented assignment for non-primitive types not yet implemented");
}
}
private void generateConcatenation(JetBinaryExpression expression) {
generateStringBuilderConstructor();
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 generateStringBuilderConstructor() {
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) {
......@@ -860,6 +879,10 @@ public class ExpressionCodegen extends JetVisitor {
}
Type exprType = expressionType(expr);
gen(expr, exprType);
invokeAppendMethod(exprType);
}
private void invokeAppendMethod(Type exprType) {
Method appendDescriptor = new Method("append", Type.getObjectType(CLASS_STRING_BUILDER),
new Type[] { exprType.getSort() == Type.OBJECT ? JetTypeMapper.TYPE_OBJECT : exprType});
v.invokevirtual(CLASS_STRING_BUILDER, "append", appendDescriptor.getDescriptor());
......@@ -934,7 +957,7 @@ public class ExpressionCodegen extends JetVisitor {
}
}
StackValue value = generateIntermediateValue(operand);
value.dupReceiver(v);
value.dupReceiver(v, 0);
value.put(asmType, v);
if (asmType == Type.LONG_TYPE) {
v.aconst(Long.valueOf(increment));
......
......@@ -24,7 +24,7 @@ public abstract class StackValue {
throw new UnsupportedOperationException("cannot store to value " + this);
}
public void dupReceiver(InstructionAdapter v) {
public void dupReceiver(InstructionAdapter v, int below) {
}
public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) {
......@@ -341,8 +341,13 @@ public abstract class StackValue {
}
@Override
public void dupReceiver(InstructionAdapter v) {
v.dup2(); // array and index
public void dupReceiver(InstructionAdapter v, int below) {
if (below == 1) {
v.dup2X1();
}
else {
v.dup2(); // array and index
}
}
}
......@@ -364,8 +369,15 @@ public abstract class StackValue {
}
@Override
public void dupReceiver(InstructionAdapter v) {
if (!isStatic) v.dup();
public void dupReceiver(InstructionAdapter v, int below) {
if (!isStatic) {
if (below == 1) {
v.dupX1();
}
else {
v.dup();
}
}
}
@Override
......
var collector: String = ""
set(it) { $collector += it }
fun append(s: String): String {
collector = s;
return collector;
}
......@@ -259,6 +259,13 @@ public class NamespaceGenTest extends CodegenTestCase {
assertEquals("jet Lang", main.invoke(null, "jet", " ", "Lang"));
}
public void testStringPlusEq() throws Exception {
loadText("fun foo(s: String) { val result = s; result += s; return result; } ");
System.out.println(generateToText());
final Method main = generateFunction();
assertEquals("JarJar", main.invoke(null, "Jar"));
}
public void testStringCompare() throws Exception {
loadText("fun foo(s1: String, s2: String) = s1 < s2");
System.out.println(generateToText());
......
......@@ -81,6 +81,15 @@ public class PropertyGenTest extends CodegenTestCase {
assertEquals(value, "IntelliJ IDEA");
}
public void testFieldSetterPlusEq() throws Exception {
loadFile("fieldSetterPlusEq.jet");
System.out.println(generateToText());
final Method method = generateFunction("append");
method.invoke(null, "IntelliJ ");
String value = (String) method.invoke(null, "IDEA");
assertEquals(value, "IntelliJ IDEA");
}
public void testAccessorsWithoutBody() throws Exception {
loadText("class AccessorsWithoutBody() { public var foo: Int = 349\n get\n private set\n fun setter() { foo = 610; } } ");
final Class aClass = loadImplementationClass(generateClassesInFile(), "AccessorsWithoutBody");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册