Any.equals & Any.toString
This commit is contained in:
@@ -1462,7 +1462,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
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) {
|
if (isNumberPrimitive(leftType) && leftType == rightType) {
|
||||||
return compareExpressionsOnStack(opToken, leftType);
|
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_BOOLEAN_TYPE = Type.getObjectType("java/lang/Boolean");
|
||||||
public static final Type JL_NUMBER_TYPE = Type.getObjectType("java/lang/Number");
|
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_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_INT_TYPE = Type.getType(int[].class);
|
||||||
public static final Type ARRAY_LONG_TYPE = Type.getType(long[].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());
|
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();
|
declareIntrinsicStringMethods();
|
||||||
declareIntrinsicProperty("String", "length", new StringLength());
|
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;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author alex.tkachman
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
@@ -13,4 +16,29 @@ public class FunctionGenTest extends CodegenTestCase {
|
|||||||
blackBoxFile("functions/nothisnoclosure.jet");
|
blackBoxFile("functions/nothisnoclosure.jet");
|
||||||
System.out.println(generateToText());
|
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"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user