KT-2417 fix: proper handling of !in
This commit is contained in:
@@ -1881,10 +1881,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
private StackValue generateIn(JetBinaryExpression expression) {
|
private StackValue generateIn(JetBinaryExpression expression) {
|
||||||
JetExpression expr = expression.getLeft();
|
JetExpression expr = expression.getLeft();
|
||||||
|
boolean inverted = expression.getOperationReference().getReferencedNameElementType() == JetTokens.NOT_IN;
|
||||||
if (isIntRangeExpr(expression.getRight())) {
|
if (isIntRangeExpr(expression.getRight())) {
|
||||||
StackValue leftValue = StackValue.expression(Type.INT_TYPE, expression.getLeft(), this);
|
StackValue leftValue = StackValue.expression(Type.INT_TYPE, expression.getLeft(), this);
|
||||||
JetBinaryExpression rangeExpression = (JetBinaryExpression) expression.getRight();
|
JetBinaryExpression rangeExpression = (JetBinaryExpression) expression.getRight();
|
||||||
boolean inverted = expression.getOperationReference().getReferencedNameElementType() == JetTokens.NOT_IN;
|
|
||||||
getInIntRange(leftValue, rangeExpression, inverted);
|
getInIntRange(leftValue, rangeExpression, inverted);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1904,6 +1904,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
v.pop();
|
v.pop();
|
||||||
}
|
}
|
||||||
invokeFunctionNoParams(op, Type.BOOLEAN_TYPE, v);
|
invokeFunctionNoParams(op, Type.BOOLEAN_TYPE, v);
|
||||||
|
if (inverted) {
|
||||||
|
invertBoolean();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
||||||
}
|
}
|
||||||
@@ -1943,8 +1946,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
v.and(Type.INT_TYPE);
|
v.and(Type.INT_TYPE);
|
||||||
if (inverted) {
|
if (inverted) {
|
||||||
v.iconst(1);
|
invertBoolean();
|
||||||
v.xor(Type.INT_TYPE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2042,8 +2044,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
if (!leftNullable) {
|
if (!leftNullable) {
|
||||||
v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
|
v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
|
||||||
if (opToken == JetTokens.EXCLEQ) {
|
if (opToken == JetTokens.EXCLEQ) {
|
||||||
v.iconst(1);
|
invertBoolean();
|
||||||
v.xor(Type.INT_TYPE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -2055,8 +2056,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
v.ifnull(leftNull);
|
v.ifnull(leftNull);
|
||||||
v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
|
v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
|
||||||
if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) {
|
if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) {
|
||||||
v.iconst(1);
|
invertBoolean();
|
||||||
v.xor(Type.INT_TYPE);
|
|
||||||
}
|
}
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
v.goTo(end);
|
v.goTo(end);
|
||||||
@@ -2080,8 +2080,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
v.ifnull(leftNull);
|
v.ifnull(leftNull);
|
||||||
v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
|
v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
|
||||||
if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) {
|
if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) {
|
||||||
v.iconst(1);
|
invertBoolean();
|
||||||
v.xor(Type.INT_TYPE);
|
|
||||||
}
|
}
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
v.goTo(end);
|
v.goTo(end);
|
||||||
@@ -3035,14 +3034,18 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
while (rangeExpression instanceof JetParenthesizedExpression) {
|
while (rangeExpression instanceof JetParenthesizedExpression) {
|
||||||
rangeExpression = ((JetParenthesizedExpression)rangeExpression).getExpression();
|
rangeExpression = ((JetParenthesizedExpression)rangeExpression).getExpression();
|
||||||
}
|
}
|
||||||
|
boolean inverted = conditionInRange.getOperationReference().getReferencedNameElementType() == JetTokens.NOT_IN;
|
||||||
if (isIntRangeExpr(rangeExpression)) {
|
if (isIntRangeExpr(rangeExpression)) {
|
||||||
getInIntRange(new StackValue.Local(subjectLocal, subjectType), (JetBinaryExpression) rangeExpression, conditionInRange.getOperationReference().getReferencedNameElementType() == JetTokens.NOT_IN);
|
getInIntRange(new StackValue.Local(subjectLocal, subjectType), (JetBinaryExpression) rangeExpression, inverted);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
FunctionDescriptor op = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, conditionInRange.getOperationReference());
|
FunctionDescriptor op = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, conditionInRange.getOperationReference());
|
||||||
genToJVMStack(rangeExpression);
|
genToJVMStack(rangeExpression);
|
||||||
new StackValue.Local(subjectLocal, subjectType).put(TYPE_OBJECT, v);
|
new StackValue.Local(subjectLocal, subjectType).put(TYPE_OBJECT, v);
|
||||||
invokeFunctionNoParams(op, Type.BOOLEAN_TYPE, v);
|
invokeFunctionNoParams(op, Type.BOOLEAN_TYPE, v);
|
||||||
|
if(inverted) {
|
||||||
|
invertBoolean();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
||||||
}
|
}
|
||||||
@@ -3065,6 +3068,11 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
subjectIsNullable, nextEntry);
|
subjectIsNullable, nextEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void invertBoolean() {
|
||||||
|
v.iconst(1);
|
||||||
|
v.xor(Type.INT_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isIntRangeExpr(JetExpression rangeExpression) {
|
private boolean isIntRangeExpr(JetExpression rangeExpression) {
|
||||||
if (rangeExpression instanceof JetBinaryExpression) {
|
if (rangeExpression instanceof JetBinaryExpression) {
|
||||||
JetBinaryExpression binaryExpression = (JetBinaryExpression) rangeExpression;
|
JetBinaryExpression binaryExpression = (JetBinaryExpression) rangeExpression;
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import java.util.HashSet
|
||||||
|
|
||||||
|
fun box() : String{
|
||||||
|
val set = HashSet<String>()
|
||||||
|
set.add("foo")
|
||||||
|
val t1 = "foo" in set // returns true, valid
|
||||||
|
if(!t1) return "fail1"
|
||||||
|
val t2 = "foo" !in set // returns true, invalid
|
||||||
|
if(t2) return "fail2"
|
||||||
|
val t3 = "bar" in set // returns false, valid
|
||||||
|
if(t3) return "fail3"
|
||||||
|
val t4 = "bar" !in set // return false, invalid
|
||||||
|
if(!t4) return "fail4"
|
||||||
|
val t5 = when("foo") {
|
||||||
|
in set -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
if(!t5) return "fail5"
|
||||||
|
val t6 = when("foo") {
|
||||||
|
!in set -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
if(t6) return "fail6"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -508,4 +508,9 @@ public class ClassGenTest extends CodegenTestCase {
|
|||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxMultiFile("regressions/kt1845_1.kt", "regressions/kt1845_2.kt");
|
blackBoxMultiFile("regressions/kt1845_1.kt", "regressions/kt1845_2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKt2417() {
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
|
blackBoxFile("regressions/kt2417.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user