fix for KT-277
This commit is contained in:
@@ -1155,6 +1155,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
else if (opToken == JetTokens.ELVIS) {
|
||||
return generateElvis(expression);
|
||||
}
|
||||
else if(opToken == JetTokens.IN_KEYWORD || opToken == JetTokens.NOT_IN) {
|
||||
return generateIn (expression);
|
||||
}
|
||||
else {
|
||||
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
|
||||
final Callable callable = resolveToCallable(op);
|
||||
@@ -1173,6 +1176,64 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
}
|
||||
|
||||
private StackValue generateIn(JetBinaryExpression expression) {
|
||||
JetExpression expr = expression.getLeft();
|
||||
StackValue leftValue = gen(expr);
|
||||
if(isIntRangeExpr(expression.getRight())) {
|
||||
JetBinaryExpression rangeExpression = (JetBinaryExpression) expression.getRight();
|
||||
boolean inverted = expression.getOperationReference().getReferencedNameElementType() == JetTokens.NOT_IN;
|
||||
getInIntTest(leftValue, rangeExpression, inverted);
|
||||
}
|
||||
else {
|
||||
leftValue.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
genToJVMStack(expression.getRight());
|
||||
v.swap();
|
||||
FunctionDescriptor op = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
|
||||
invokeFunctionNoParams(op, Type.BOOLEAN_TYPE, v);
|
||||
}
|
||||
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
||||
}
|
||||
|
||||
private void getInIntTest(StackValue leftValue, JetBinaryExpression rangeExpression, boolean inverted) {
|
||||
v.iconst(1);
|
||||
// 1
|
||||
leftValue.put(Type.INT_TYPE, v);
|
||||
// 1 l
|
||||
v.dup2();
|
||||
// 1 l 1 l
|
||||
|
||||
//noinspection ConstantConditions
|
||||
gen(rangeExpression.getLeft(), Type.INT_TYPE);
|
||||
// 1 l 1 l r
|
||||
Label lok = new Label();
|
||||
v.ificmpge(lok);
|
||||
// 1 l 1
|
||||
v.pop();
|
||||
v.iconst(0);
|
||||
v.mark(lok);
|
||||
// 1 l c
|
||||
v.dupX2();
|
||||
// c 1 l c
|
||||
v.pop();
|
||||
// c 1 l
|
||||
|
||||
gen(rangeExpression.getRight(), Type.INT_TYPE);
|
||||
// c 1 l r
|
||||
Label rok = new Label();
|
||||
v.ificmple(rok);
|
||||
// c 1
|
||||
v.pop();
|
||||
v.iconst(0);
|
||||
v.mark(rok);
|
||||
// c c
|
||||
|
||||
v.and(Type.INT_TYPE);
|
||||
if(inverted) {
|
||||
v.iconst(1);
|
||||
v.xor(Type.INT_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
private StackValue generateBooleanAnd(JetBinaryExpression expression) {
|
||||
gen(expression.getLeft(), Type.BOOLEAN_TYPE);
|
||||
Label ifFalse = new Label();
|
||||
@@ -1986,38 +2047,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return StackValue.onStack(expressionType(expression));
|
||||
}
|
||||
|
||||
private StackValue generateWhenCondition(Type subjectType, int subjectLocal, JetWhenCondition condition,
|
||||
@Nullable Label nextEntry) {
|
||||
private StackValue generateWhenCondition(Type subjectType, int subjectLocal, JetWhenCondition condition, @Nullable Label nextEntry) {
|
||||
StackValue conditionValue;
|
||||
if (condition instanceof JetWhenConditionInRange) {
|
||||
JetWhenConditionInRange conditionInRange = (JetWhenConditionInRange) condition;
|
||||
JetExpression rangeExpression = conditionInRange.getRangeExpression();
|
||||
if(isIntRangeExpr(rangeExpression)) {
|
||||
v.iconst(1);
|
||||
//noinspection ConstantConditions
|
||||
new StackValue.Local(subjectLocal, subjectType).put(Type.INT_TYPE, v);
|
||||
JetBinaryExpression binaryExpression = (JetBinaryExpression) rangeExpression;
|
||||
gen(binaryExpression.getLeft(), Type.INT_TYPE);
|
||||
Label lok = new Label();
|
||||
v.ificmpge(lok);
|
||||
v.pop();
|
||||
v.iconst(0);
|
||||
v.mark(lok);
|
||||
|
||||
v.iconst(1);
|
||||
new StackValue.Local(subjectLocal, subjectType).put(Type.INT_TYPE, v);
|
||||
gen(binaryExpression.getRight(), Type.INT_TYPE);
|
||||
Label rok = new Label();
|
||||
v.ificmple(rok);
|
||||
v.pop();
|
||||
v.iconst(0);
|
||||
v.mark(rok);
|
||||
|
||||
v.and(Type.INT_TYPE);
|
||||
if(conditionInRange.getOperationReference().getReferencedNameElementType() == JetTokens.NOT_IN) {
|
||||
v.iconst(1);
|
||||
v.xor(Type.INT_TYPE);
|
||||
}
|
||||
getInIntTest(new StackValue.Local(subjectLocal, subjectType), (JetBinaryExpression) rangeExpression, conditionInRange.getOperationReference().getReferencedNameElementType() == JetTokens.NOT_IN);
|
||||
}
|
||||
else {
|
||||
FunctionDescriptor op = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, conditionInRange.getOperationReference());
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
fun isDigit(a: Int) : String {
|
||||
val aa = java.util.ArrayList<Int> ()
|
||||
aa.add(239)
|
||||
|
||||
if(a in aa) return "array list"
|
||||
if(a in 0..9) return "digit"
|
||||
if(a !in 0..100) return "not small"
|
||||
return "something"
|
||||
}
|
||||
@@ -35,6 +35,18 @@ public class PatternMatchingTest extends CodegenTestCase {
|
||||
assertEquals("something", foo.invoke(null, new Object()));
|
||||
}
|
||||
|
||||
public void testInrange() throws Exception {
|
||||
loadFile();
|
||||
System.out.println(generateToText());
|
||||
Method foo = generateFunction();
|
||||
assertEquals("array list", foo.invoke(null, 239));
|
||||
assertEquals("digit", foo.invoke(null, 0));
|
||||
assertEquals("digit", foo.invoke(null, 9));
|
||||
assertEquals("digit", foo.invoke(null, 5));
|
||||
assertEquals("not small", foo.invoke(null, 190));
|
||||
assertEquals("something", foo.invoke(null, 19));
|
||||
}
|
||||
|
||||
public void testRange() throws Exception {
|
||||
loadFile();
|
||||
System.out.println(generateToText());
|
||||
|
||||
Reference in New Issue
Block a user