From fbd0af0914191f786bdcaeaddd0c01a173a2a347 Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Thu, 15 Feb 2018 20:50:18 +0300 Subject: [PATCH] Support `and`, `or` and `not` on booleans in PyEvaluator (PY-19856) --- .../python/psi/impl/PyEvaluator.java | 25 +++++++++++++++++++ .../com/jetbrains/python/PyEvaluatorTest.java | 6 +++++ 2 files changed, 31 insertions(+) diff --git a/python/src/com/jetbrains/python/psi/impl/PyEvaluator.java b/python/src/com/jetbrains/python/psi/impl/PyEvaluator.java index babc553f24cb..cc71f722a8f5 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyEvaluator.java +++ b/python/src/com/jetbrains/python/psi/impl/PyEvaluator.java @@ -98,6 +98,9 @@ public class PyEvaluator { else if (expression instanceof PyNumericLiteralExpression) { return evaluateNumeric((PyNumericLiteralExpression)expression); } + else if (expression instanceof PyPrefixExpression) { + return evaluatePrefix((PyPrefixExpression)expression); + } return null; } @@ -152,6 +155,16 @@ public class PyEvaluator { return first.compareTo(second) != 0; } } + else if (lhs instanceof Boolean && rhs instanceof Boolean) { + final Boolean first = (Boolean)lhs; + final Boolean second = (Boolean)rhs; + if (op == PyTokenTypes.AND_KEYWORD) { + return first && second; + } + else if (op == PyTokenTypes.OR_KEYWORD) { + return first || second; + } + } return null; } @@ -174,6 +187,18 @@ public class PyEvaluator { return null; } + @Nullable + private Object evaluatePrefix(@NotNull PyPrefixExpression expression) { + if (expression.getOperator() == PyTokenTypes.NOT_KEYWORD) { + final Boolean value = PyUtil.as(evaluate(expression.getOperand()), Boolean.class); + if (value != null) { + return !value; + } + } + + return null; + } + /** * Evaluates sequence (tuple, list, set, dict) * diff --git a/python/testSrc/com/jetbrains/python/PyEvaluatorTest.java b/python/testSrc/com/jetbrains/python/PyEvaluatorTest.java index 5240a3712987..e96607330252 100644 --- a/python/testSrc/com/jetbrains/python/PyEvaluatorTest.java +++ b/python/testSrc/com/jetbrains/python/PyEvaluatorTest.java @@ -249,6 +249,12 @@ public class PyEvaluatorTest extends PyTestCase { assertTrue(byExpression("2 != 1", Boolean.class)); } + public void testBooleanOperators() { + assertTrue(byExpression("True and True", Boolean.class)); + assertTrue(byExpression("True or False", Boolean.class)); + assertTrue(byExpression("not False", Boolean.class)); + } + @NotNull private T byExpression(@NotNull String expression, @NotNull Class cls) { final Object value = new PyEvaluator().evaluate(parseExpression(expression));