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
This commit is contained in:
Denis Zhdanov
2011-02-18 12:03:12 +03:00
parent 798430dd63
commit 5fe8f15981
5 changed files with 40 additions and 12 deletions
@@ -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();
}
}
@@ -0,0 +1,5 @@
class Test {
Test(boolean condition) {
if (condition<caret>)
}
}
@@ -0,0 +1,7 @@
class Test {
Test(boolean condition) {
if (condition) {
<caret>
}
}
}
@@ -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());
@@ -46,7 +46,7 @@ public abstract class EditorActionTestCase extends LightCodeInsightTestCase {
}
/**
* Perform action test using text before and after action perform. Useas &lt;caret&gt; marker where caret should be
* Perform action test using text before and after action perform. Uses &lt;caret&gt; marker where caret should be
* placed when file is loaded in editor and &lt;selection&gt;&lt;/selection&gt; 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.