+= for strings
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
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");
|
||||
|
||||
Reference in New Issue
Block a user