From b3523f52407246b3b0ccb8b53ec3c0886aa98ba8 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Fri, 29 Aug 2014 10:56:56 +0400 Subject: [PATCH] java: handle { after if/while statement condition and insert new block statement if needed --- .../editorActions/JavaTypedHandler.java | 29 ++++++++++++++++++- .../typing/fixIfByBrace_after.java | 7 +++++ .../typing/fixIfByBrace_before.java | 5 ++++ .../typing/fixWhileByBrace_after.java | 7 +++++ .../typing/fixWhileByBrace_before.java | 5 ++++ .../intellij/codeInsight/JavaTypingTest.java | 8 +++++ 6 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/typing/fixIfByBrace_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/fixIfByBrace_before.java create mode 100644 java/java-tests/testData/codeInsight/typing/fixWhileByBrace_after.java create mode 100644 java/java-tests/testData/codeInsight/typing/fixWhileByBrace_before.java diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java index e2dedf5ea3ec..70698d4ad609 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java @@ -18,6 +18,8 @@ package com.intellij.codeInsight.editorActions; import com.intellij.codeInsight.AutoPopupController; import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.completion.JavaClassReferenceCompletionContributor; +import com.intellij.codeInsight.editorActions.smartEnter.JavaSmartEnterProcessor; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorModificationUtil; import com.intellij.openapi.editor.ex.EditorEx; @@ -125,11 +127,18 @@ public class JavaTypedHandler extends TypedHandlerDelegate { if (iterator.atEnd() || iterator.getTokenType() == JavaTokenType.RBRACKET || iterator.getTokenType() == JavaTokenType.EQ) { return Result.CONTINUE; } - PsiDocumentManager.getInstance(project).commitDocument(editor.getDocument()); + Document doc = editor.getDocument(); + PsiDocumentManager.getInstance(project).commitDocument(doc); final PsiElement leaf = file.findElementAt(offset); if (PsiTreeUtil.getParentOfType(leaf, PsiArrayInitializerExpression.class, false, PsiCodeBlock.class, PsiMember.class) != null) { return Result.CONTINUE; } + PsiElement st = leaf != null ? leaf.getParent() : null; + if (CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET && isRparenth(leaf) && + (st instanceof PsiWhileStatement || st instanceof PsiIfStatement) && noBody(st, doc)) { + new JavaSmartEnterProcessor().process(project, editor, file); + return Result.STOP; + } if (PsiTreeUtil.getParentOfType(leaf, PsiCodeBlock.class, false, PsiMember.class) != null) { EditorModificationUtil.insertStringAtCaret(editor, "{"); TypedHandler.indentOpenedBrace(project, editor); @@ -140,6 +149,24 @@ public class JavaTypedHandler extends TypedHandlerDelegate { return Result.CONTINUE; } + private static boolean noBody(@NotNull PsiElement statement, @NotNull Document doc) { + PsiStatement block = statement instanceof PsiWhileStatement ? ((PsiWhileStatement)statement).getBody() : ((PsiIfStatement)statement).getThenBranch(); + PsiExpression condition = PsiTreeUtil.getChildOfType(statement, PsiExpression.class); + return !(block instanceof PsiBlockStatement) && (block == null || startLine(doc, block) != startLine(doc, statement) || condition == null); + } + + private static boolean isRparenth(@Nullable PsiElement leaf) { + if (leaf == null) return false; + if (leaf.getNode().getElementType() == JavaTokenType.RPARENTH) return true; + PsiElement next = PsiTreeUtil.nextVisibleLeaf(leaf); + if (next == null) return false; + return next.getNode().getElementType() == JavaTokenType.RPARENTH; + } + + private static int startLine(@NotNull Document doc, @NotNull PsiElement psiElement) { + return doc.getLineNumber(psiElement.getTextRange().getStartOffset()); + } + @Override public Result charTyped(final char c, final Project project, @NotNull final Editor editor, @NotNull final PsiFile file) { if (myJavaLTTyped) { diff --git a/java/java-tests/testData/codeInsight/typing/fixIfByBrace_after.java b/java/java-tests/testData/codeInsight/typing/fixIfByBrace_after.java new file mode 100644 index 000000000000..f17312c07aa6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/fixIfByBrace_after.java @@ -0,0 +1,7 @@ +class C { + boolean f() { + if (f()) { + + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/fixIfByBrace_before.java b/java/java-tests/testData/codeInsight/typing/fixIfByBrace_before.java new file mode 100644 index 000000000000..017a62e874f3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/fixIfByBrace_before.java @@ -0,0 +1,5 @@ +class C { + boolean f() { + if (f()) + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/fixWhileByBrace_after.java b/java/java-tests/testData/codeInsight/typing/fixWhileByBrace_after.java new file mode 100644 index 000000000000..92e28bfe1542 --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/fixWhileByBrace_after.java @@ -0,0 +1,7 @@ +class C { + boolean f() { + while (f()) { + + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/typing/fixWhileByBrace_before.java b/java/java-tests/testData/codeInsight/typing/fixWhileByBrace_before.java new file mode 100644 index 000000000000..a254dee776db --- /dev/null +++ b/java/java-tests/testData/codeInsight/typing/fixWhileByBrace_before.java @@ -0,0 +1,5 @@ +class C { + boolean f() { + while (f()) + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java index 9ca3b6084a43..6b12df69216b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/JavaTypingTest.java @@ -74,6 +74,14 @@ public class JavaTypingTest extends LightPlatformCodeInsightFixtureTestCase { myFixture.checkResultByFile(getTestName(true) + "_after.java"); } + public void testFixIfByBrace() { + doTest('{'); + } + + public void testFixWhileByBrace() { + doTest('{'); + } + private void doTest(char c) { myFixture.configureByFile(getTestName(true) + "_before.java"); myFixture.type(c);