PY-25605 EA-85878 Fix NPE: handle incomplete expressions in PyDemorganIntention

This commit is contained in:
Mikhail Golubev
2017-10-03 17:55:31 +03:00
parent f8decd9867
commit 7d07533771
4 changed files with 28 additions and 9 deletions
@@ -66,6 +66,7 @@ public class PyDemorganIntention extends PyBaseIntentionAction {
PyBinaryExpression.class);
assert expression != null;
final PyElementType op = expression.getOperator();
assert op != null;
final String converted = convertConjunctionExpression(expression, op);
replaceExpression(converted, expression);
}
@@ -85,7 +86,8 @@ public class PyDemorganIntention extends PyBaseIntentionAction {
// TODO codeStyleManager.reformat(insertedElement)
}
private static String convertConjunctionExpression(PyBinaryExpression exp, PyElementType tokenType) {
@NotNull
private static String convertConjunctionExpression(@NotNull PyBinaryExpression exp, @NotNull PyElementType tokenType) {
final PyExpression lhs = exp.getLeftExpression();
final String lhsText;
final String rhsText;
@@ -108,8 +110,12 @@ public class PyDemorganIntention extends PyBaseIntentionAction {
return lhsText + flippedConjunction + rhsText;
}
private static String convertLeafExpression(PyExpression condition) {
if (isNegation(condition)) {
@NotNull
private static String convertLeafExpression(@Nullable PyExpression condition) {
if (condition == null) {
return "";
}
else if (isNegation(condition)) {
final PyExpression negated = getNegated(condition);
if (negated == null) {
return "";
@@ -125,11 +131,11 @@ public class PyDemorganIntention extends PyBaseIntentionAction {
}
@Nullable
private static PyExpression getNegated(PyExpression expression) {
private static PyExpression getNegated(@NotNull PyExpression expression) {
return ((PyPrefixExpression)expression).getOperand(); // TODO strip ()
}
private static boolean isConjunctionExpression(PyExpression expression, PyElementType tokenType) {
private static boolean isConjunctionExpression(@Nullable PyExpression expression, @NotNull PyElementType tokenType) {
if (expression instanceof PyBinaryExpression) {
final PyElementType operator = ((PyBinaryExpression)expression).getOperator();
return operator == tokenType;
@@ -137,7 +143,7 @@ public class PyDemorganIntention extends PyBaseIntentionAction {
return false;
}
private static boolean isNegation(PsiElement expression) {
private static boolean isNegation(@Nullable PsiElement expression) {
if (!(expression instanceof PyPrefixExpression)) {
return false;
}
@@ -0,0 +1,2 @@
if a and b <caret>and :
pass
@@ -0,0 +1,2 @@
if not (not a or not b or):
pass
@@ -20,18 +20,27 @@ import com.jetbrains.python.PyBundle;
public class PythonDemorganLawIntentionTest extends PyIntentionTestCase {
public void testOr() {
doIntentionTest(PyBundle.message("INTN.demorgan.law"));
doTest();
}
public void testNotOr() {
doIntentionTest(PyBundle.message("INTN.demorgan.law"));
doTest();
}
public void testOrNot() {
doIntentionTest(PyBundle.message("INTN.demorgan.law"));
doTest();
}
public void testComplex() {
doTest();
}
// PY-25605
public void testMissingOperand() {
doTest();
}
private void doTest() {
doIntentionTest(PyBundle.message("INTN.demorgan.law"));
}
}