put values of correct type on stack for checking if character is in range
This commit is contained in:
@@ -51,6 +51,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
private static final String INT_RANGE_CONSTRUCTOR_DESCRIPTOR = "(II)V";
|
private static final String INT_RANGE_CONSTRUCTOR_DESCRIPTOR = "(II)V";
|
||||||
|
|
||||||
private static final Type OBJECT_TYPE = Type.getType(Object.class);
|
private static final Type OBJECT_TYPE = Type.getType(Object.class);
|
||||||
|
private static final Type INTEGER_TYPE = Type.getType(Integer.class);
|
||||||
private static final Type ITERATOR_TYPE = Type.getType(Iterator.class);
|
private static final Type ITERATOR_TYPE = Type.getType(Iterator.class);
|
||||||
private static final Type THROWABLE_TYPE = Type.getType(Throwable.class);
|
private static final Type THROWABLE_TYPE = Type.getType(Throwable.class);
|
||||||
|
|
||||||
@@ -1026,7 +1027,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
|
|
||||||
private void generateRange(JetBinaryExpression expression) {
|
private void generateRange(JetBinaryExpression expression) {
|
||||||
final Type leftType = expressionType(expression.getLeft());
|
final Type leftType = expressionType(expression.getLeft());
|
||||||
if (isIntPrimitive(leftType)) {
|
if (JetTypeMapper.isIntPrimitive(leftType)) {
|
||||||
v.anew(INT_RANGE_TYPE);
|
v.anew(INT_RANGE_TYPE);
|
||||||
v.dup();
|
v.dup();
|
||||||
gen(expression.getLeft(), Type.INT_TYPE);
|
gen(expression.getLeft(), Type.INT_TYPE);
|
||||||
@@ -1058,11 +1059,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isNumberPrimitive(Type type) {
|
private static boolean isNumberPrimitive(Type type) {
|
||||||
return isIntPrimitive(type) || type == Type.FLOAT_TYPE || type == Type.DOUBLE_TYPE || type == Type.LONG_TYPE;
|
return JetTypeMapper.isIntPrimitive(type) || type == Type.FLOAT_TYPE || type == Type.DOUBLE_TYPE || type == Type.LONG_TYPE;
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isIntPrimitive(Type type) {
|
|
||||||
return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int opcodeForMethod(final String name) {
|
private static int opcodeForMethod(final String name) {
|
||||||
@@ -1242,7 +1239,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
int increment = op.getName().equals("inc") ? 1 : -1;
|
int increment = op.getName().equals("inc") ? 1 : -1;
|
||||||
if (operand instanceof JetReferenceExpression) {
|
if (operand instanceof JetReferenceExpression) {
|
||||||
final int index = indexOfLocal((JetReferenceExpression) operand);
|
final int index = indexOfLocal((JetReferenceExpression) operand);
|
||||||
if (index >= 0 && isIntPrimitive(asmType)) {
|
if (index >= 0 && JetTypeMapper.isIntPrimitive(asmType)) {
|
||||||
v.iinc(index, increment);
|
v.iinc(index, increment);
|
||||||
return StackValue.local(index, asmType);
|
return StackValue.local(index, asmType);
|
||||||
}
|
}
|
||||||
@@ -1617,7 +1614,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
else if (condition instanceof JetWhenConditionInRange) {
|
else if (condition instanceof JetWhenConditionInRange) {
|
||||||
JetExpression range = ((JetWhenConditionInRange) condition).getRangeExpression();
|
JetExpression range = ((JetWhenConditionInRange) condition).getRangeExpression();
|
||||||
gen(range, RANGE_TYPE);
|
gen(range, RANGE_TYPE);
|
||||||
new StackValue.Local(subjectLocal, subjectType).put(OBJECT_TYPE, v);
|
new StackValue.Local(subjectLocal, subjectType).put(INTEGER_TYPE, v);
|
||||||
v.invokeinterface(CLASS_RANGE, "contains", "(Ljava/lang/Comparable;)Z");
|
v.invokeinterface(CLASS_RANGE, "contains", "(Ljava/lang/Comparable;)Z");
|
||||||
myStack.push(new StackValue.OnStack(Type.BOOLEAN_TYPE));
|
myStack.push(new StackValue.OnStack(Type.BOOLEAN_TYPE));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ public class JetTypeMapper {
|
|||||||
return qName.replace(".", "/");
|
return qName.replace(".", "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean isIntPrimitive(Type type) {
|
||||||
|
return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
public String jvmName(ClassDescriptor jetClass, OwnerKind kind) {
|
public String jvmName(ClassDescriptor jetClass, OwnerKind kind) {
|
||||||
PsiElement declaration = bindingContext.getDeclarationPsiElement(jetClass);
|
PsiElement declaration = bindingContext.getDeclarationPsiElement(jetClass);
|
||||||
if (declaration instanceof PsiClass) {
|
if (declaration instanceof PsiClass) {
|
||||||
|
|||||||
@@ -75,8 +75,9 @@ public abstract class StackValue {
|
|||||||
return new Property(name, fieldOwner, interfaceOwner, getter, setter, isStatic, type);
|
return new Property(name, fieldOwner, interfaceOwner, getter, setter, isStatic, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void box(final Type type, InstructionAdapter v) {
|
private static void box(final Type type, final Type toType, InstructionAdapter v) {
|
||||||
if (type == Type.INT_TYPE) {
|
// TODO handle toType correctly
|
||||||
|
if (type == Type.INT_TYPE || (JetTypeMapper.isIntPrimitive(type) && toType.getInternalName().equals("java/lang/Integer"))) {
|
||||||
v.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
|
v.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
|
||||||
}
|
}
|
||||||
else if (type == Type.BOOLEAN_TYPE) {
|
else if (type == Type.BOOLEAN_TYPE) {
|
||||||
@@ -131,7 +132,7 @@ public abstract class StackValue {
|
|||||||
|
|
||||||
protected void coerce(Type type, InstructionAdapter v) {
|
protected void coerce(Type type, InstructionAdapter v) {
|
||||||
if (type.getSort() == Type.OBJECT) {
|
if (type.getSort() == Type.OBJECT) {
|
||||||
box(this.type, v);
|
box(this.type, type, v);
|
||||||
}
|
}
|
||||||
else if (this.type.getSort() == Type.OBJECT && type.getSort() <= Type.DOUBLE) {
|
else if (this.type.getSort() == Type.OBJECT && type.getSort() <= Type.DOUBLE) {
|
||||||
unbox(type, v);
|
unbox(type, v);
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun isDigit(a: Char) = when(a) {
|
||||||
|
in '0'..'9' => "digit"
|
||||||
|
else => "something"
|
||||||
|
}
|
||||||
@@ -155,7 +155,12 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
|
|||||||
|
|
||||||
protected Method generateFunction() {
|
protected Method generateFunction() {
|
||||||
Class aClass = generateNamespaceClass();
|
Class aClass = generateNamespaceClass();
|
||||||
return aClass.getMethods()[0];
|
try {
|
||||||
|
return aClass.getMethods()[0];
|
||||||
|
} catch (Error e) {
|
||||||
|
System.out.println(generateToText());
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Method generateFunction(String name) {
|
protected Method generateFunction(String name) {
|
||||||
|
|||||||
@@ -42,6 +42,14 @@ public class PatternMatchingTest extends CodegenTestCase {
|
|||||||
assertEquals("something", foo.invoke(null, 19));
|
assertEquals("something", foo.invoke(null, 19));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testRangeChar() throws Exception {
|
||||||
|
loadFile();
|
||||||
|
System.out.println(generateToText());
|
||||||
|
Method foo = generateFunction();
|
||||||
|
assertEquals("digit", foo.invoke(null, '0'));
|
||||||
|
assertEquals("something", foo.invoke(null, 'A'));
|
||||||
|
}
|
||||||
|
|
||||||
public void testWildcardPattern() throws Exception {
|
public void testWildcardPattern() throws Exception {
|
||||||
loadText("fun foo(x: String) = when(x) { is * => \"something\" }");
|
loadText("fun foo(x: String) = when(x) { is * => \"something\" }");
|
||||||
Method foo = generateFunction();
|
Method foo = generateFunction();
|
||||||
|
|||||||
Reference in New Issue
Block a user