KT-13931 generate IntRange#contains with awareness of inverse in operator

This commit is contained in:
Vsevolod
2016-09-24 00:56:54 +03:00
committed by Dmitry Petrov
parent 1ac07340c9
commit ff7c7538d4
@@ -3448,21 +3448,21 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
final KtExpression deparenthesized = KtPsiUtil.deparenthesize(rangeExpression); final KtExpression deparenthesized = KtPsiUtil.deparenthesize(rangeExpression);
assert deparenthesized != null : "For with empty range expression"; assert deparenthesized != null : "For with empty range expression";
final boolean isInverted = operationReference.getReferencedNameElementType() == KtTokens.NOT_IN;
return StackValue.operation(Type.BOOLEAN_TYPE, new Function1<InstructionAdapter, Unit>() { return StackValue.operation(Type.BOOLEAN_TYPE, new Function1<InstructionAdapter, Unit>() {
@Override @Override
public Unit invoke(InstructionAdapter v) { public Unit invoke(InstructionAdapter v) {
if (isIntRangeExpr(deparenthesized) && AsmUtil.isIntPrimitive(leftValue.type)) { if (isIntRangeExpr(deparenthesized) && AsmUtil.isIntPrimitive(leftValue.type)) {
genInIntRange(leftValue, (KtBinaryExpression) deparenthesized); genInIntRange(leftValue, (KtBinaryExpression) deparenthesized, isInverted);
} }
else { else {
ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt
.getResolvedCallWithAssert(operationReference, bindingContext); .getResolvedCallWithAssert(operationReference, bindingContext);
StackValue result = invokeFunction(resolvedCall.getCall(), resolvedCall, StackValue.none()); StackValue result = invokeFunction(resolvedCall.getCall(), resolvedCall, StackValue.none());
result.put(result.type, v); result.put(result.type, v);
} if (isInverted) {
if (operationReference.getReferencedNameElementType() == KtTokens.NOT_IN) { genInvertBoolean(v);
genInvertBoolean(v); }
} }
return null; return null;
} }
@@ -3471,8 +3471,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
/* /*
* Translates x in a..b (for int and char ranges only) to a <= x && x <= b * Translates x in a..b (for int and char ranges only) to a <= x && x <= b
* and x !in a..b to a > x || x > b
*/ */
private void genInIntRange(StackValue leftValue, KtBinaryExpression rangeExpression) { private void genInIntRange(StackValue leftValue, KtBinaryExpression rangeExpression, boolean isInverted) {
int localVarIndex = myFrameMap.enterTemp(Type.INT_TYPE); int localVarIndex = myFrameMap.enterTemp(Type.INT_TYPE);
// Load left bound // Load left bound
@@ -3492,11 +3493,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
v.ificmpgt(l1); v.ificmpgt(l1);
Label l2 = new Label(); Label l2 = new Label();
v.iconst(1); v.iconst(isInverted ? 0 : 1);
v.goTo(l2); v.goTo(l2);
v.mark(l1); v.mark(l1);
v.iconst(0); v.iconst(isInverted? 1 : 0);
v.mark(l2); v.mark(l2);
myFrameMap.leaveTemp(Type.INT_TYPE); myFrameMap.leaveTemp(Type.INT_TYPE);
} }