diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java index 67eee98c8917..0b2a95ea7cc3 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java @@ -205,7 +205,7 @@ class ConstructorInsertHandler implements InsertHandler methods = OverrideImplementUtil.overrideOrImplementMethodCandidates(aClass, candidatesToImplement, false); List> prototypes = OverrideImplementUtil.convert2GenerationInfos(methods); List> resultMembers = GenerateMembersUtil.insertMembersBeforeAnchor(aClass, null, prototypes); - GenerateMembersUtil.positionCaret(editor, resultMembers.get(0).getPsiMember(), true); + resultMembers.get(0).positionCaret(editor, true); } catch(IncorrectOperationException ioe){ LOG.error(ioe); @@ -260,7 +260,7 @@ class ConstructorInsertHandler implements InsertHandler> resultMembers = GenerateMembersUtil.insertMembersAtOffset(aClass.getContainingFile(), offset, prototypes); - GenerateMembersUtil.positionCaret(editor, resultMembers.get(0).getPsiMember(), true); + resultMembers.get(0).positionCaret(editor, true); } catch(IncorrectOperationException e){ LOG.error(e); diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java index a42018e62eb8..5dfbc930f5c6 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersHandlerBase.java @@ -134,7 +134,7 @@ public abstract class GenerateMembersHandlerBase implements CodeInsightActionHan runTemplates(project, editor, templates, 0); } else if (!newMembers.isEmpty()){ - GenerateMembersUtil.positionCaret(editor, newMembers.get(0).getPsiMember(), false); + newMembers.get(0).positionCaret(editor, false); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java index ec4b6f30f89e..bcfed2f6269c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java @@ -119,6 +119,9 @@ public class GenerateMembersUtil { return memberPrototypes; } + /** + * @see GenerationInfo#positionCaret(com.intellij.openapi.editor.Editor, boolean) + */ public static void positionCaret(@NotNull Editor editor, @NotNull PsiElement firstMember, boolean toEditMethodBody) { LOG.assertTrue(firstMember.isValid()); diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerationInfoBase.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerationInfoBase.java index eef3e5a3fba3..99ab33b9622d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerationInfoBase.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerationInfoBase.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.generation; +import com.intellij.openapi.editor.Editor; import com.intellij.psi.JavaTokenType; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; @@ -58,4 +59,8 @@ public abstract class GenerationInfoBase implements GenerationInfo { } return element; } + + public void positionCaret(Editor editor, boolean toEditMethodBody) { + GenerateMembersUtil.positionCaret(editor, getPsiMember(), toEditMethodBody); + } } diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java index 4497f059865b..08e87459fa0e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java @@ -670,7 +670,7 @@ public class OverrideImplementUtil { } if (!resultMembers.isEmpty()) { - GenerateMembersUtil.positionCaret(editor, resultMembers.get(0).getPsiMember(), true); + resultMembers.get(0).positionCaret(editor, true); } } catch(IncorrectOperationException e){ @@ -724,10 +724,11 @@ public class OverrideImplementUtil { Editor editor = fileEditorManager.openTextEditor(new OpenFileDescriptor(psiFile.getProject(), psiFile.getVirtualFile()), false); if (editor == null) return; - GenerateMembersUtil.positionCaret(editor, results.get(0).getPsiMember(), true); + results.get(0).positionCaret(editor, true); editor.getScrollingModel().scrollToCaret(ScrollType.CENTER); } + @Nullable public static PsiClass getContextClass(Project project, Editor editor, PsiFile file, boolean allowInterface) { PsiDocumentManager.getInstance(project).commitAllDocuments(); @@ -740,8 +741,7 @@ public class OverrideImplementUtil { final PsiClass aClass = (PsiClass)element; if (aClass instanceof JspClass) return null; - return aClass == null || - !allowInterface && aClass.isInterface() ? null : aClass; + return aClass == null || !allowInterface && aClass.isInterface() ? null : aClass; } private static PsiSubstitutor getContextSubstitutor(PsiClass aClass) { diff --git a/java/openapi/src/com/intellij/codeInsight/generation/GenerationInfo.java b/java/openapi/src/com/intellij/codeInsight/generation/GenerationInfo.java index 49e765f1942c..5b2bb5e8eb0f 100644 --- a/java/openapi/src/com/intellij/codeInsight/generation/GenerationInfo.java +++ b/java/openapi/src/com/intellij/codeInsight/generation/GenerationInfo.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.generation; +import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMember; @@ -39,4 +40,9 @@ public interface GenerationInfo { */ @Nullable PsiElement findInsertionAnchor(@NotNull PsiClass aClass, @NotNull PsiElement leaf); + + /** + * Position caret in generated element in correct way + */ + void positionCaret(Editor editor, boolean toEditMethodBody); } \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/generate/GroovyGenerationInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/generate/GroovyGenerationInfo.java index 75f848506971..3faf0f5ed852 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/generate/GroovyGenerationInfo.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/generate/GroovyGenerationInfo.java @@ -17,6 +17,9 @@ package org.jetbrains.plugins.groovy.actions.generate; import com.intellij.codeInsight.generation.GenerateMembersUtil; import com.intellij.codeInsight.generation.PsiGenerationInfo; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ScrollType; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMember; @@ -25,12 +28,19 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; + +import static org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil.isWhiteSpace; /** * @author peter */ -public class GroovyGenerationInfo extends PsiGenerationInfo{ +public class GroovyGenerationInfo extends PsiGenerationInfo { + private static final Logger LOG = Logger.getInstance(GroovyGenerationInfo.class); + public GroovyGenerationInfo(@NotNull T member, boolean mergeIfExists) { super(member, mergeIfExists); } @@ -78,4 +88,56 @@ public class GroovyGenerationInfo extends PsiGenerationInfo return element; } + + @Override + public void positionCaret(Editor editor, boolean toEditMethodBody) { + final T firstMember = getPsiMember(); + LOG.assertTrue(firstMember.isValid()); + + if (toEditMethodBody) { + GrMethod method = (GrMethod)firstMember; + GrOpenBlock body = method.getBlock(); + if (body != null) { + PsiElement l = body.getLBrace(); + if (l != null) l = l.getNextSibling(); + while (isWhiteSpace(l)) l = l.getNextSibling(); + if (l == null) l = body; + + PsiElement r = body.getRBrace(); + if (r != null) r = r.getPrevSibling(); + while (isWhiteSpace(r)) r = r.getPrevSibling(); + if (r == null) r = body; + + int start = l.getTextRange().getStartOffset(); + int end = r.getTextRange().getEndOffset(); + + editor.getCaretModel().moveToOffset(Math.min(start, end)); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + if (start < end) { + //Not an empty body + editor.getSelectionModel().setSelection(start, end); + } + return; + } + } + + int offset; + if (firstMember instanceof GrMethod) { + GrMethod method = (GrMethod)firstMember; + GrCodeBlock body = method.getBlock(); + if (body == null) { + offset = method.getTextRange().getStartOffset(); + } + else { + offset = body.getLBrace().getTextRange().getEndOffset(); + } + } + else { + offset = firstMember.getTextRange().getStartOffset(); + } + + editor.getCaretModel().moveToOffset(offset); + editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); + editor.getSelectionModel().removeSelection(); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/selection/GroovyBlockStatementsSelectioner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/selection/GroovyBlockStatementsSelectioner.java index 6980dc1e583e..284d07a52812 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/selection/GroovyBlockStatementsSelectioner.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/editor/selection/GroovyBlockStatementsSelectioner.java @@ -19,8 +19,8 @@ package org.jetbrains.plugins.groovy.editor.selection; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; -import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; +import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import java.util.List; @@ -50,7 +50,7 @@ public class GroovyBlockStatementsSelectioner extends GroovyBasicSelectioner { PsiElement lbrace = block.getLBrace(); if (lbrace == null) return block.getTextRange().getStartOffset(); - while (isWhiteSpace(lbrace.getNextSibling())) { + while (PsiImplUtil.isWhiteSpace(lbrace.getNextSibling())) { lbrace = lbrace.getNextSibling(); } return lbrace.getTextRange().getEndOffset(); @@ -60,14 +60,10 @@ public class GroovyBlockStatementsSelectioner extends GroovyBasicSelectioner { PsiElement rbrace = block.getRBrace(); if (rbrace == null) return block.getTextRange().getEndOffset(); - while (isWhiteSpace(rbrace.getPrevSibling()) && rbrace.getPrevSibling().getTextRange().getStartOffset() > startOffset) { + while (PsiImplUtil.isWhiteSpace(rbrace.getPrevSibling()) && rbrace.getPrevSibling().getTextRange().getStartOffset() > startOffset) { rbrace = rbrace.getPrevSibling(); } return rbrace.getTextRange().getStartOffset(); } - - private static boolean isWhiteSpace(PsiElement element) { - return element != null && TokenSets.WHITE_SPACES_SET.contains(element.getNode().getElementType()); - } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java index 45f97711df72..fd65881d29d5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java @@ -40,6 +40,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.formatter.GeeseUtil; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; +import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.psi.GrNamedElement; import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; @@ -674,6 +675,9 @@ public class PsiImplUtil { if (ref==null) return false; final String text = ref.getText(); return text.startsWith("java.") || text.startsWith("javax."); - } - + } + + public static boolean isWhiteSpace(PsiElement element) { + return element != null && TokenSets.WHITE_SPACES_SET.contains(element.getNode().getElementType()); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/overrideImplement/GroovyOverrideImplementUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/overrideImplement/GroovyOverrideImplementUtil.java index e485b06a732f..0767cedcaf18 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/overrideImplement/GroovyOverrideImplementUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/overrideImplement/GroovyOverrideImplementUtil.java @@ -186,7 +186,7 @@ public class GroovyOverrideImplementUtil { try { String bodyText = StringUtil.replace(template.getText(properties), ";", ""); - final GrCodeBlock newBody = GroovyPsiElementFactory.getInstance(project).createMethodBodyFromText("\n" + bodyText + "\n"); + final GrCodeBlock newBody = GroovyPsiElementFactory.getInstance(project).createMethodBodyFromText("\n " + bodyText + "\n"); resultMethod.setBlock(newBody); } diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/GenerateMainAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/GenerateMainAction.java index 0b90e10c4cd1..530ab8b7c1bd 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/GenerateMainAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/GenerateMainAction.java @@ -116,7 +116,7 @@ public class GenerateMainAction extends AnAction { JavaPsiFacade.getInstance(file.getProject()).getElementFactory().createMethodFromText(mainBuilder.toString(), file); List> infos = Collections.singletonList(new PsiGenerationInfo(method)); List> resultMembers = GenerateMembersUtil.insertMembersAtOffset(file, offset, infos); - GenerateMembersUtil.positionCaret(editor, resultMembers.get(0).getPsiMember(), false); + resultMembers.get(0).positionCaret(editor, false); } catch (IncorrectOperationException e1) { LOG.error(e1);