Any.equals & Any.toString

This commit is contained in:
Alex Tkachman
2011-10-21 18:41:27 +02:00
parent 23c72f4e27
commit fe869a236d
6 changed files with 102 additions and 1 deletions
@@ -1462,7 +1462,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return StackValue.onStack(Type.BOOLEAN_TYPE);
}
private StackValue generateEqualsForExpressionsOnStack(IElementType opToken, Type leftType, Type rightType, boolean leftNullable, boolean rightNullable) {
public StackValue generateEqualsForExpressionsOnStack(IElementType opToken, Type leftType, Type rightType, boolean leftNullable, boolean rightNullable) {
if (isNumberPrimitive(leftType) && leftType == rightType) {
return compareExpressionsOnStack(opToken, leftType);
}
@@ -39,6 +39,7 @@ public class JetTypeMapper {
public static final Type JL_BOOLEAN_TYPE = Type.getObjectType("java/lang/Boolean");
public static final Type JL_NUMBER_TYPE = Type.getObjectType("java/lang/Number");
public static final Type JL_STRING_BUILDER = Type.getObjectType("java/lang/StringBuilder");
public static final Type JL_STRING_TYPE = Type.getObjectType("java/lang/String");
public static final Type ARRAY_INT_TYPE = Type.getType(int[].class);
public static final Type ARRAY_LONG_TYPE = Type.getType(long[].class);
@@ -0,0 +1,43 @@
package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lexer.JetTokens;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
/**
* @author alex.tkachman
*/
public class Equals implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
boolean leftNullable = true;
if(element instanceof JetCallExpression) {
JetCallExpression jetCallExpression = (JetCallExpression) element;
JetExpression calleeExpression = jetCallExpression.getCalleeExpression();
if(calleeExpression != null) {
JetType leftType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, calleeExpression);
if(leftType != null)
leftNullable = leftType.isNullable();
}
}
JetExpression rightExpr = arguments.get(0);
JetType rightType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, rightExpr);
codegen.gen(rightExpr).put(JetTypeMapper.TYPE_OBJECT, v);
return codegen.generateEqualsForExpressionsOnStack(JetTokens.EQEQ, JetTypeMapper.TYPE_OBJECT, JetTypeMapper.TYPE_OBJECT, leftNullable, rightType.isNullable());
}
}
@@ -73,6 +73,11 @@ public class IntrinsicMethods {
declareIntrinsicFunction("String", "plus", 1, new Concat());
declareOverload(myStdLib.getLibraryScope().getFunctions("toString"), 0, new ToString());
declareOverload(myStdLib.getLibraryScope().getFunctions("equals"), 1, new Equals());
// declareIntrinsicFunction("Any", "equals", 1, new Equals());
//
declareIntrinsicStringMethods();
declareIntrinsicProperty("String", "length", new StringLength());
@@ -0,0 +1,24 @@
package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
/**
* @author alex.tkachman
*/
public class ToString implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
v.invokestatic("java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;");
return StackValue.onStack(JetTypeMapper.JL_STRING_TYPE);
}
}
@@ -1,5 +1,8 @@
package org.jetbrains.jet.codegen;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author alex.tkachman
*/
@@ -13,4 +16,29 @@ public class FunctionGenTest extends CodegenTestCase {
blackBoxFile("functions/nothisnoclosure.jet");
System.out.println(generateToText());
}
public void testAnyToString () throws InvocationTargetException, IllegalAccessException {
loadText("fun foo(x: Any) = x.toString()");
System.out.println(generateToText());
Method foo = generateFunction();
assertEquals("something", foo.invoke(null, "something"));
assertEquals("null", foo.invoke(null, new Object[]{null}));
}
public void testAnyEqualsNullable () throws InvocationTargetException, IllegalAccessException {
loadText("fun foo(x: Any?) = x.equals(\"lala\")");
System.out.println(generateToText());
Method foo = generateFunction();
assertTrue((Boolean) foo.invoke(null, "lala"));
assertFalse((Boolean) foo.invoke(null, "mama"));
}
public void testAnyEquals () throws InvocationTargetException, IllegalAccessException {
loadText("fun foo(x: Any) = x.equals(\"lala\")");
System.out.println(generateToText());
Method foo = generateFunction();
assertTrue((Boolean) foo.invoke(null, "lala"));
assertFalse((Boolean) foo.invoke(null, "mama"));
}
}