From 5fe8f15981e2485ee8fde8b4f5e4c22aa81a6cc1 Mon Sep 17 00:00:00 2001 From: Denis Zhdanov Date: Fri, 18 Feb 2011 12:02:05 +0300 Subject: [PATCH] IDEA-65434 Ctrl+Shift+Enter bug in conditional blocks Corrected situation when we complete statement with empty code block and code style is set to keep simple instructions in one line --- .../smartEnter/PlainEnterProcessor.java | 28 +++++++++++++------ .../completeStatement/BeforeIfRBrace.java | 5 ++++ .../BeforeIfRBrace_after.java | 7 +++++ .../codeInsight/CompleteStatementTest.java | 6 ++++ .../testFramework/EditorActionTestCase.java | 6 ++-- 5 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completeStatement/BeforeIfRBrace.java create mode 100644 java/java-tests/testData/codeInsight/completeStatement/BeforeIfRBrace_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java index b8d06069838e..7c9c2bd5fde1 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/smartEnter/PlainEnterProcessor.java @@ -21,6 +21,7 @@ import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.editor.actionSystem.EditorActionManager; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.psi.*; +import org.jetbrains.annotations.Nullable; /** * Created by IntelliJ IDEA. @@ -32,30 +33,39 @@ import com.intellij.psi.*; public class PlainEnterProcessor implements EnterProcessor { public boolean doEnter(Editor editor, PsiElement psiElement, boolean isModified) { PsiCodeBlock block = getControlStatementBlock(editor.getCaretModel().getOffset(), psiElement); + EditorActionHandler enterHandler = getEnterHandler(IdeActions.ACTION_EDITOR_START_NEW_LINE); if (block != null) { PsiElement firstElement = block.getFirstBodyElement(); - if (firstElement == null) firstElement = block.getRBrace(); + if (firstElement == null) { + firstElement = block.getRBrace(); + // Plain enter processor inserts enter after the end of line, hence, we don't want to use it here because the line ends with + // the empty braces block. So, we get the following in case of default handler usage: + // Before: + // if (condition[caret]) {} + // After: + // if (condition) {} + // [caret] + enterHandler = getEnterHandler(IdeActions.ACTION_EDITOR_ENTER); + } editor.getCaretModel().moveToOffset(firstElement != null ? firstElement.getTextRange().getStartOffset() : block.getTextRange().getEndOffset()); } - getEnterHandler().execute(editor, ((EditorEx)editor).getDataContext()); + enterHandler.execute(editor, ((EditorEx)editor).getDataContext()); return true; } - private EditorActionHandler getEnterHandler() { - EditorActionHandler enterHandler = EditorActionManager.getInstance().getActionHandler( - IdeActions.ACTION_EDITOR_START_NEW_LINE - ); - return enterHandler; + private static EditorActionHandler getEnterHandler(String actionId) { + return EditorActionManager.getInstance().getActionHandler(actionId); } - private PsiCodeBlock getControlStatementBlock(int caret, PsiElement element) { + @Nullable + private static PsiCodeBlock getControlStatementBlock(int caret, PsiElement element) { PsiStatement body = null; if (element instanceof PsiIfStatement) { body = ((PsiIfStatement)element).getThenBranch(); - if (caret > body.getTextRange().getEndOffset()) { + if (body != null && caret > body.getTextRange().getEndOffset()) { body = ((PsiIfStatement)element).getElseBranch(); } } diff --git a/java/java-tests/testData/codeInsight/completeStatement/BeforeIfRBrace.java b/java/java-tests/testData/codeInsight/completeStatement/BeforeIfRBrace.java new file mode 100644 index 000000000000..b539e691af88 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completeStatement/BeforeIfRBrace.java @@ -0,0 +1,5 @@ +class Test { + Test(boolean condition) { + if (condition) + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completeStatement/BeforeIfRBrace_after.java b/java/java-tests/testData/codeInsight/completeStatement/BeforeIfRBrace_after.java new file mode 100644 index 000000000000..ae33296297b1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completeStatement/BeforeIfRBrace_after.java @@ -0,0 +1,7 @@ +class Test { + Test(boolean condition) { + if (condition) { + + } + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java index d63d98fe8239..5ccafe430ead 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/CompleteStatementTest.java @@ -5,6 +5,7 @@ import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.testFramework.EditorActionTestCase; @@ -191,6 +192,11 @@ public class CompleteStatementTest extends EditorActionTestCase { public void testIDEA25139() throws Exception { doTestBracesNextLineStyle(); } + + public void testBeforeIfRBrace() throws Exception { + CodeStyleSettingsManager.getSettings(getProject()).KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = true; + doTest(); + } private void doTestBracesNextLineStyle() throws Exception { CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject()); diff --git a/java/testFramework/src/com/intellij/testFramework/EditorActionTestCase.java b/java/testFramework/src/com/intellij/testFramework/EditorActionTestCase.java index c68fa81008ad..7f915ac9fb4b 100644 --- a/java/testFramework/src/com/intellij/testFramework/EditorActionTestCase.java +++ b/java/testFramework/src/com/intellij/testFramework/EditorActionTestCase.java @@ -46,7 +46,7 @@ public abstract class EditorActionTestCase extends LightCodeInsightTestCase { } /** - * Perform action test using text before and after action perform. Useas <caret> marker where caret should be + * Perform action test using text before and after action perform. Uses <caret> marker where caret should be * placed when file is loaded in editor and <selection></selection> denoting selection bounds. * @param fileName name of the file. Mostly used to create proper instance of the PsiFile * @param textBefore text with markers before action @@ -68,7 +68,7 @@ public abstract class EditorActionTestCase extends LightCodeInsightTestCase { } /** - * Same as doTextTest but texts are retreived from the data files. + * Same as doTextTest but texts are retrieved from the data files. * @param filePathBefore source file's relative path from %IDEA_INSTALLATION_HOME%/testData/ * @param filePathAfter expected file's relative path from %IDEA_INSTALLATION_HOME%/testData/ * @throws Exception @@ -78,7 +78,7 @@ public abstract class EditorActionTestCase extends LightCodeInsightTestCase { } /** - * Same as doTextTest but texts are retreived from the data files. + * Same as doTextTest but texts are retrieved from the data files. * @param filePathBefore source file's relative path from %IDEA_INSTALLATION_HOME%/testData/ * @param filePathAfter expected file's relative path from %IDEA_INSTALLATION_HOME%/testData/ * @param ignoreTrailingSpaces true if trailing spaces should be ignored.