From d4914b0f5b9690a590eac6c96e1f9de2b0a73a52 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 7 Feb 2020 12:43:20 +0700 Subject: [PATCH] IDEA-76990 Completion for 'instanceof' keyword in negative conditions. GitOrigin-RevId: 07a917d6b5fbee806796237acd639341a90d49dc --- .../completion/JavaKeywordCompletion.java | 51 ++++++++++++------- .../keywords/instanceofNegated.java | 7 +++ .../keywords/instanceofNegated_after.java | 7 +++ .../completion/KeywordCompletionTest.java | 1 + 4 files changed, 49 insertions(+), 17 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/keywords/instanceofNegated.java create mode 100644 java/java-tests/testData/codeInsight/completion/keywords/instanceofNegated_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java index b3b126224ae7..fa2afd382572 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java @@ -24,6 +24,7 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.util.Consumer; import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; +import com.siyeh.ig.psiutils.BoolUtils; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -521,25 +522,34 @@ public class JavaKeywordCompletion { if (isInstanceofPlace(myPosition)) { addKeyword(LookupElementDecorator.withInsertHandler( createKeyword(PsiKeyword.INSTANCEOF), - new InsertHandler>() { - @Override - public void handleInsert(@NotNull InsertionContext context, @NotNull LookupElementDecorator item) { - TailType tailType = TailType.HUMBLE_SPACE_BEFORE_WORD; - if (tailType.isApplicable(context)) { - tailType.processTail(context.getEditor(), context.getTailOffset()); - } + (context, item) -> { + TailType tailType = TailType.HUMBLE_SPACE_BEFORE_WORD; + if (tailType.isApplicable(context)) { + tailType.processTail(context.getEditor(), context.getTailOffset()); + } - if ('!' == context.getCompletionChar()) { - context.setAddCompletionChar(false); - context.commitDocument(); - PsiInstanceOfExpression expr = - PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiInstanceOfExpression.class, false); - if (expr != null) { + if ('!' == context.getCompletionChar()) { + context.setAddCompletionChar(false); + } + context.commitDocument(); + PsiInstanceOfExpression expr = + PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiInstanceOfExpression.class, false); + if (expr != null) { + PsiExpression operand = expr.getOperand(); + if (operand instanceof PsiPrefixExpression && + ((PsiPrefixExpression)operand).getOperationTokenType().equals(JavaTokenType.EXCL)) { + PsiExpression negated = ((PsiPrefixExpression)operand).getOperand(); + if (negated != null) { String space = CompletionStyleUtil.getCodeStyleSettings(context).SPACE_WITHIN_PARENTHESES ? " " : ""; - context.getDocument().insertString(expr.getTextRange().getStartOffset(), "!(" + space); + context.getDocument().insertString(negated.getTextRange().getStartOffset(), "(" + space); context.getDocument().insertString(context.getTailOffset(), space + ")"); } } + else if ('!' == context.getCompletionChar()) { + String space = CompletionStyleUtil.getCodeStyleSettings(context).SPACE_WITHIN_PARENTHESES ? " " : ""; + context.getDocument().insertString(expr.getTextRange().getStartOffset(), "!(" + space); + context.getDocument().insertString(context.getTailOffset(), space + ")"); + } } })); } @@ -626,9 +636,16 @@ public class JavaKeywordCompletion { if (psiElement().insideStarting(psiElement(PsiClassObjectAccessExpression.class)).accepts(position)) return true; PsiElement parent = position.getParent(); - return parent instanceof PsiReferenceExpression && - !((PsiReferenceExpression)parent).isQualified() && - !JavaCompletionContributor.IN_SWITCH_LABEL.accepts(position); + if (!(parent instanceof PsiReferenceExpression) || + ((PsiReferenceExpression)parent).isQualified() || + JavaCompletionContributor.IN_SWITCH_LABEL.accepts(position)) { + return false; + } + if (parent.getParent() instanceof PsiExpressionStatement) { + PsiElement previous = PsiTreeUtil.skipWhitespacesBackward(parent.getParent()); + return previous == null || !(previous.getLastChild() instanceof PsiErrorElement); + } + return true; } public static boolean isInstanceofPlace(PsiElement position) { diff --git a/java/java-tests/testData/codeInsight/completion/keywords/instanceofNegated.java b/java/java-tests/testData/codeInsight/completion/keywords/instanceofNegated.java new file mode 100644 index 000000000000..44633e1428b0 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/keywords/instanceofNegated.java @@ -0,0 +1,7 @@ +class Foo { + void test(Object o) { + if (!o in) { + + } + } +} diff --git a/java/java-tests/testData/codeInsight/completion/keywords/instanceofNegated_after.java b/java/java-tests/testData/codeInsight/completion/keywords/instanceofNegated_after.java new file mode 100644 index 000000000000..ecbd937a016e --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/keywords/instanceofNegated_after.java @@ -0,0 +1,7 @@ +class Foo { + void test(Object o) { + if (!(o instanceof )) { + + } + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/KeywordCompletionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/KeywordCompletionTest.java index f91ab8c669c3..9b1a94197843 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/KeywordCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/KeywordCompletionTest.java @@ -101,6 +101,7 @@ public class KeywordCompletionTest extends LightCompletionTestCase { public void testInstanceofAfterStatementStart() { doTest(1, "instanceof"); } public void testNoInstanceofInAnnotation() { doTest(0, "instanceof"); } + public void testInstanceofNegated() { doTest(); } public void testInstanceofNegation() { configureByTestName(); selectItem(myItems[0], '!');