less/greater comparisons for IComparable objects

This commit is contained in:
Dmitry Jemerov
2011-04-15 11:50:54 +02:00
parent f7d00f2dec
commit 3a203302dc
2 changed files with 24 additions and 13 deletions
@@ -25,6 +25,7 @@ public class ExpressionCodegen extends JetVisitor {
private static final String CLASS_OBJECT = "java/lang/Object"; private static final String CLASS_OBJECT = "java/lang/Object";
private static final String CLASS_STRING = "java/lang/String"; private static final String CLASS_STRING = "java/lang/String";
private static final String CLASS_STRING_BUILDER = "java/lang/StringBuilder"; private static final String CLASS_STRING_BUILDER = "java/lang/StringBuilder";
private static final String CLASS_COMPARABLE = "java/lang/Comparable";
private final Stack<Label> myLoopStarts = new Stack<Label>(); private final Stack<Label> myLoopStarts = new Stack<Label>();
private final Stack<Label> myLoopEnds = new Stack<Label>(); private final Stack<Label> myLoopEnds = new Stack<Label>();
@@ -511,20 +512,17 @@ public class ExpressionCodegen extends JetVisitor {
opToken == JetTokens.EQEQEQ || opToken == JetTokens.EXCLEQEQEQ) { opToken == JetTokens.EQEQEQ || opToken == JetTokens.EXCLEQEQEQ) {
generateEquals(expression, opToken); generateEquals(expression, opToken);
} }
else if (opToken == JetTokens.LT || opToken == JetTokens.LTEQ ||
opToken == JetTokens.GT || opToken == JetTokens.GTEQ) {
generateCompareOp(expression, opToken, expressionType(expression.getLeft()));
}
else { else {
DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationReference()); DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationReference());
if (op instanceof FunctionDescriptor) { if (op instanceof FunctionDescriptor) {
JetType returnType = bindingContext.getExpressionType(expression);
final Type asmType = typeMapper.mapType(returnType);
DeclarationDescriptor cls = op.getContainingDeclaration(); DeclarationDescriptor cls = op.getContainingDeclaration();
if (isNumberPrimitive(cls)) { if (isNumberPrimitive(cls)) {
if (op.getName().equals("compareTo")) { int opcode = opcodeForMethod(op.getName());
generateCompareOp(expression, opToken, asmType); generateBinaryOp(expression, (FunctionDescriptor) op, opcode);
}
else {
int opcode = opcodeForMethod(op.getName());
generateBinaryOp(expression, (FunctionDescriptor) op, opcode);
}
return; return;
} }
else if (isClass(cls, "String") && op.getName().equals("plus")) { else if (isClass(cls, "String") && op.getName().equals("plus")) {
@@ -667,10 +665,15 @@ public class ExpressionCodegen extends JetVisitor {
} }
} }
private void generateCompareOp(JetBinaryExpression expression, IElementType opToken, Type type) { private void generateCompareOp(JetBinaryExpression expression, IElementType opToken, Type operandType) {
gen(expression.getLeft(), type); gen(expression.getLeft(), operandType);
gen(expression.getRight(), type); gen(expression.getRight(), operandType);
myStack.push(StackValue.cmp(opToken, type)); if (operandType.getSort() == Type.OBJECT) {
v.invokeinterface(CLASS_COMPARABLE, "compareTo", "(Ljava/lang/Object;)I");
v.aconst(0);
operandType = Type.INT_TYPE;
}
myStack.push(StackValue.cmp(opToken, operandType));
} }
private void generateAssignmentExpression(JetBinaryExpression expression) { private void generateAssignmentExpression(JetBinaryExpression expression) {
@@ -578,6 +578,14 @@ public class NamespaceGenTest extends LightCodeInsightFixtureTestCase {
assertEquals("jet Lang", main.invoke(null, "jet", " ", "Lang")); assertEquals("jet Lang", main.invoke(null, "jet", " ", "Lang"));
} }
public void testStringCompare() throws Exception {
loadText("fun foo(s1: String, s2: String) = s1 < s2");
System.out.println(generateToText());
final Method main = generateFunction();
assertEquals(Boolean.TRUE, main.invoke(null, "Ceylon", "Java"));
assertEquals(Boolean.FALSE, main.invoke(null, "Jet", "Java"));
}
private void binOpTest(final String text, final Object arg1, final Object arg2, final Object expected) throws Exception { private void binOpTest(final String text, final Object arg1, final Object arg2, final Object expected) throws Exception {
loadText(text); loadText(text);
System.out.println(generateToText()); System.out.println(generateToText());