IDEA-73264 GenerationInfo manages caret position for the generated member

This commit is contained in:
Maxim.Medvedev
2012-02-10 13:02:22 +04:00
parent db484241dc
commit 826bd5cabb
11 changed files with 95 additions and 19 deletions
@@ -205,7 +205,7 @@ class ConstructorInsertHandler implements InsertHandler<LookupElementDecorator<L
List<PsiMethod> methods = OverrideImplementUtil.overrideOrImplementMethodCandidates(aClass, candidatesToImplement, false);
List<PsiGenerationInfo<PsiMethod>> prototypes = OverrideImplementUtil.convert2GenerationInfos(methods);
List<PsiGenerationInfo<PsiMethod>> 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<LookupElementDecorator<L
}
List<PsiGenerationInfo<PsiMethod>> 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);
@@ -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);
}
}
@@ -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());
@@ -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);
}
}
@@ -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) {
@@ -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);
}
@@ -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<T extends PsiMember> extends PsiGenerationInfo<T>{
public class GroovyGenerationInfo<T extends PsiMember> extends PsiGenerationInfo<T> {
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<T extends PsiMember> 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();
}
}
@@ -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());
}
}
@@ -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());
}
}
@@ -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);
}
@@ -116,7 +116,7 @@ public class GenerateMainAction extends AnAction {
JavaPsiFacade.getInstance(file.getProject()).getElementFactory().createMethodFromText(mainBuilder.toString(), file);
List<PsiGenerationInfo<PsiMethod>> infos = Collections.singletonList(new PsiGenerationInfo<PsiMethod>(method));
List<PsiGenerationInfo<PsiMethod>> 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);