From 06a603eec06832df90d1db5ef40e5269ea679e69 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Mon, 6 Feb 2012 14:37:12 +0400 Subject: [PATCH] IDEA-80287 Incorrect cursor placement on Ctrl-Shift-Enter in Groovy code --- .../smartEnter/fixers/GrMethodBodyFixer.java | 14 ++++---- .../processors/GroovyPlainEnterProcessor.java | 35 +++++++++++++------ .../lang/smartEnter/SmartEnterTest.java | 8 ++++- .../smartEnter/methodBodyAtNextLine.test | 6 ++++ 4 files changed, 45 insertions(+), 18 deletions(-) create mode 100644 plugins/groovy/testdata/groovy/actions/smartEnter/methodBodyAtNextLine.test diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/smartEnter/fixers/GrMethodBodyFixer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/smartEnter/fixers/GrMethodBodyFixer.java index 5af20679a58b..eddfea2a46d3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/smartEnter/fixers/GrMethodBodyFixer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/smartEnter/fixers/GrMethodBodyFixer.java @@ -15,16 +15,17 @@ */ package org.jetbrains.plugins.groovy.lang.completion.smartEnter.fixers; -import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.IncorrectOperationException; +import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiModifier; +import com.intellij.util.IncorrectOperationException; import org.jetbrains.plugins.groovy.lang.completion.smartEnter.GroovySmartEnterProcessor; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; /** * User: Dmitry.Krasilschikov @@ -34,13 +35,14 @@ public class GrMethodBodyFixer implements GrFixer { public void apply(Editor editor, GroovySmartEnterProcessor processor, PsiElement psiElement) throws IncorrectOperationException { if (!(psiElement instanceof GrMethod)) return; GrMethod method = (GrMethod) psiElement; - if (method.getContainingClass().isInterface() || method.hasModifierProperty(PsiModifier.ABSTRACT)) return; + final PsiClass aClass = method.getContainingClass(); + if (aClass != null && aClass.isInterface() || method.hasModifierProperty(PsiModifier.ABSTRACT)) return; final GrCodeBlock body = method.getBlock(); final Document doc = editor.getDocument(); if (body != null) { // See IDEADEV-1093. This is quite hacky heuristic but it seem to be best we can do. String bodyText = body.getText(); - if (bodyText.startsWith("{")) { + if (StringUtil.startsWithChar(bodyText, '{')) { final GrStatement[] statements = body.getStatements(); if (statements.length > 0) { // [todo] diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/smartEnter/processors/GroovyPlainEnterProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/smartEnter/processors/GroovyPlainEnterProcessor.java index 8ddab9bcce21..c8068ea98a05 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/smartEnter/processors/GroovyPlainEnterProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/smartEnter/processors/GroovyPlainEnterProcessor.java @@ -15,14 +15,16 @@ */ package org.jetbrains.plugins.groovy.lang.completion.smartEnter.processors; -import com.intellij.psi.PsiElement; import com.intellij.codeInsight.editorActions.smartEnter.EnterProcessor; +import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorActionManager; import com.intellij.openapi.editor.ex.EditorEx; -import com.intellij.openapi.actionSystem.IdeActions; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; /** * User: Dmitry.Krasilschikov @@ -45,19 +47,30 @@ public class GroovyPlainEnterProcessor implements EnterProcessor { return true; } + @Nullable private static GrCodeBlock getControlStatementBlock(int caret, PsiElement element) { GrStatement body = null; + + if (element instanceof GrMethod) return ((GrMethod)element).getBlock(); + if (element instanceof GrIfStatement) { - body = ((GrIfStatement) element).getThenBranch(); - if (caret > body.getTextRange().getEndOffset()) { - body = ((GrIfStatement) element).getElseBranch(); + body = ((GrIfStatement)element).getThenBranch(); + if (body != null && caret > body.getTextRange().getEndOffset()) { + body = ((GrIfStatement)element).getElseBranch(); } - } else if (element instanceof GrWhileStatement) { - body = ((GrWhileStatement) element).getBody(); - } else if (element instanceof GrForStatement) { - body = ((GrForStatement) element).getBody(); + } + else if (element instanceof GrWhileStatement) { + body = ((GrWhileStatement)element).getBody(); + } + else if (element instanceof GrForStatement) { + body = ((GrForStatement)element).getBody(); } - return body instanceof GrBlockStatement ? ((GrBlockStatement) body).getBlock() : null; + if (body instanceof GrBlockStatement) { + return ((GrBlockStatement)body).getBlock(); + } + + + return null; } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/smartEnter/SmartEnterTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/smartEnter/SmartEnterTest.java index c0636a8c06b6..d7e9e97d4412 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/smartEnter/SmartEnterTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/smartEnter/SmartEnterTest.java @@ -1,6 +1,8 @@ package org.jetbrains.plugins.groovy.lang.smartEnter; import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.util.TestUtils; @@ -37,8 +39,12 @@ public class SmartEnterTest extends LightCodeInsightFixtureTestCase { public void testListFixer() throws Throwable {doTest();} public void testSwitchBraces() throws Throwable {doTest();} public void testCatchClause() throws Throwable {doTest();} + public void testMethodBodyAtNextLine() { + CodeStyleSettingsManager.getSettings(myFixture.getProject()).getCommonSettings(GroovyFileType.GROOVY_LANGUAGE).METHOD_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; + doTest(); + } - public void doTest() throws Exception { + public void doTest() { final List data = TestUtils.readInput(getTestDataPath() + getTestName(true) + ".test"); myFixture.configureByText(GroovyFileType.GROOVY_FILE_TYPE, data.get(0)); diff --git a/plugins/groovy/testdata/groovy/actions/smartEnter/methodBodyAtNextLine.test b/plugins/groovy/testdata/groovy/actions/smartEnter/methodBodyAtNextLine.test new file mode 100644 index 000000000000..c2560671ba12 --- /dev/null +++ b/plugins/groovy/testdata/groovy/actions/smartEnter/methodBodyAtNextLine.test @@ -0,0 +1,6 @@ +def foo() +------ +def foo() +{ + +} \ No newline at end of file