diff --git a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/OccurrencesChooser.java b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/OccurrencesChooser.java index 04a67b29b829..444bc492aa81 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/OccurrencesChooser.java +++ b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/OccurrencesChooser.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,7 +44,7 @@ import java.util.List; // This prevents languages with polyadic expressions or sequences // from reusing it, use simpleChooser instead. public abstract class OccurrencesChooser { - public static enum ReplaceChoice { + public enum ReplaceChoice { NO("Replace this occurrence only"), NO_WRITE("Replace all occurrences but write"), ALL("Replace all {0} occurrences"); private final String myDescription; diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java index 33f23494b341..fc7335595a10 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/InplaceRefactoring.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import com.intellij.lang.refactoring.NamesValidator; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.Shortcut; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.Result; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.command.impl.FinishMarkAction; @@ -327,7 +328,7 @@ public abstract class InplaceRefactoring { new WriteCommandAction(myProject, getCommandName()) { @Override - protected void run(com.intellij.openapi.application.Result result) throws Throwable { + protected void run(Result result) throws Throwable { startTemplate(builder); } }.execute(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrAbstractInplaceIntroducer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrAbstractInplaceIntroducer.java new file mode 100644 index 000000000000..32004067b0ca --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrAbstractInplaceIntroducer.java @@ -0,0 +1,277 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.refactoring.introduce; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.RangeMarker; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.Computable; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtilCore; +import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer; +import com.intellij.refactoring.introduce.inplace.OccurrencesChooser; +import com.intellij.util.Function; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.GroovyFileType; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; +import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; + +import java.util.List; + + +/** + * Created by Max Medvedev on 10/28/13 + */ +public abstract class GrAbstractInplaceIntroducer extends AbstractInplaceIntroducer { + + private SmartTypePointer myTypePointer; + private OccurrencesChooser.ReplaceChoice myReplaceChoice; + + private RangeMarker myVarMarker; + private final PsiFile myFile; + + private final GrIntroduceContext myContext; + + public GrAbstractInplaceIntroducer(String title, + OccurrencesChooser.ReplaceChoice replaceChoice, + GrIntroduceContext context) { + super(context.getProject(), context.getEditor(), context.getExpression(), context.getVar(), context.getOccurrences(), title, GroovyFileType.GROOVY_FILE_TYPE); + myReplaceChoice = replaceChoice; + myContext = context; + myFile = context.getPlace().getContainingFile(); + } + + public GrIntroduceContext getContext() { + return myContext; + } + + @Override + public void setReplaceAllOccurrences(boolean allOccurrences) { + throw new IncorrectOperationException("don't invoke this method"); + } + + @Override + public GrExpression restoreExpression(PsiFile containingFile, GrVariable variable, RangeMarker marker, String exprText) { + if (exprText == null) return null; + if (variable == null || !variable.isValid()) return null; + final PsiElement refVariableElement = containingFile.findElementAt(marker.getStartOffset()); + final PsiElement refVariableElementParent = refVariableElement != null ? refVariableElement.getParent() : null; + GrExpression expression = + refVariableElementParent instanceof GrNewExpression && refVariableElement.getNode().getElementType() == GroovyTokenTypes.kNEW + ? (GrNewExpression)refVariableElementParent + : PsiTreeUtil.getParentOfType(refVariableElement, GrReferenceExpression.class); + if (expression instanceof GrReferenceExpression && !(expression.getParent() instanceof GrMethodCall)) { + final String referenceName = ((GrReferenceExpression)expression).getReferenceName(); + if (((GrReferenceExpression)expression).resolve() == variable || + Comparing.strEqual(variable.getName(), referenceName) || + Comparing.strEqual(exprText, referenceName)) { + return (GrExpression)expression + .replace(GroovyPsiElementFactory.getInstance(myProject).createExpressionFromText(exprText, variable)); + } + } + if (expression == null) { + expression = PsiTreeUtil.getParentOfType(refVariableElement, GrExpression.class); + } + while (expression instanceof GrReferenceExpression) { + final PsiElement parent = expression.getParent(); + if (parent instanceof GrMethodCallExpression) { + if (parent.getText().equals(exprText)) return (GrExpression)parent; + } + if (parent instanceof GrExpression) { + expression = (GrExpression)parent; + if (expression.getText().equals(exprText)) { + return expression; + } + } + else { + return null; + } + } + if (expression != null && expression.isValid() && expression.getText().equals(exprText)) { + return expression; + } + + if (refVariableElementParent instanceof GrExpression && refVariableElementParent.getText().equals(exprText)) { + return (GrExpression)refVariableElementParent; + } + + return null; + } + + @Override + protected void updateTitle(@Nullable GrVariable variable, String value) { + if (variable == null) { + super.updateTitle(variable, value); + } + else { + final String variableText = variable.getParent().getText(); + final PsiElement identifier = variable.getNameIdentifierGroovy(); + final int startOffsetInParent = identifier.getStartOffsetInParent() + variable.getStartOffsetInParent(); + setPreviewText( + variableText.substring(0, startOffsetInParent) + value + variableText.substring(startOffsetInParent + identifier.getTextLength())); + revalidate(); + } + } + + @Override + protected void updateTitle(@Nullable GrVariable variable) { + if (variable == null) return; + setPreviewText(variable.getParent().getText()); + revalidate(); + } + + @Nullable + @Override + protected PsiElement getNameIdentifier() { + return ((GrVariable)myElementToRename).getNameIdentifierGroovy(); + } + + @Override + protected GrVariable getVariable() { + if (myVarMarker == null) return null; + + int offset = myVarMarker.getStartOffset(); + PsiElement at = myFile.findElementAt(offset); + GrVariable var = PsiTreeUtil.getParentOfType(at, GrVariable.class); + return var; + } + + @Override + protected void performIntroduce() { + final List markers = getOccurrenceMarkers(); + GrIntroduceContext context = new GrIntroduceContext() { + @NotNull + @Override + public Project getProject() { + return myProject; + } + + @Override + public Editor getEditor() { + return myEditor; + } + + @Nullable + @Override + public GrExpression getExpression() { + return (GrExpression)getExpr(); + } + + @Nullable + @Override + public GrVariable getVar() { + return getLocalVariable(); + } + + @Nullable + @Override + public StringPartInfo getStringPart() { + return null; + } + + @NotNull + @Override + public PsiElement[] getOccurrences() { + List result = ContainerUtil.map(markers, new Function() { + @Override + public PsiElement fun(RangeMarker marker) { + return GroovyRefactoringUtil.findElementInRange(myFile, marker.getStartOffset(), marker.getEndOffset(), GrExpression.class); + } + }); + return PsiUtilCore.toPsiElementArray(result); + } + + @Override + public PsiElement getScope() { + return myScope; + } + + @NotNull + @Override + public PsiElement getPlace() { + GrExpression expression = getExpression(); + return expression != null ? expression : getLocalVariable(); + } + }; + runRefactoring(context, getSettings(), true); + } + + @Nullable + @Override + protected GrVariable createFieldToStartTemplateOn(boolean replaceAll, String[] names) { + + final Settings settings = getInitialSettingsForInplace(myContext, myReplaceChoice, names); + if (settings == null) return null; + + SmartPsiElementPointer pointer = ApplicationManager.getApplication().runWriteAction(new Computable>() { + @Override + public SmartPsiElementPointer compute() { + GrVariable var = runRefactoring(myContext, settings, false); + return var != null ? SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(var) : null; + } + }); + + if (pointer != null) { + GrVariable var = pointer.getElement(); + if (var != null) { + myVarMarker = myContext.getEditor().getDocument().createRangeMarker(var.getTextRange()); + } + return var; + } + else { + return null; + } + } + + protected abstract GrVariable runRefactoring(GrIntroduceContext context, Settings settings, boolean processUsages); + + @Nullable + protected abstract Settings getInitialSettingsForInplace(@NotNull GrIntroduceContext context, + @NotNull OccurrencesChooser.ReplaceChoice choice, + String[] names); + + @Override + public boolean isReplaceAllOccurrences() { + return myReplaceChoice != OccurrencesChooser.ReplaceChoice.NO || myContext.getOccurrences().length == 1; + } + + protected abstract Settings getSettings(); + + @Override + protected void restoreState(GrVariable psiField) { + PsiType declaredType = psiField.getDeclaredType(); + myTypePointer = declaredType != null ? SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(declaredType) : null; + super.restoreState(psiField); + } + + @Nullable + protected PsiType getSelectedType() { + return myTypePointer != null ? myTypePointer.getType() : null; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java index ec3aefa1c717..6e147414b669 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java @@ -21,7 +21,6 @@ import com.intellij.lang.LanguageRefactoringSupport; import com.intellij.lang.refactoring.RefactoringSupportProvider; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; @@ -32,7 +31,6 @@ import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pass; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.wm.WindowManager; @@ -77,7 +75,7 @@ import java.util.*; import static org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.skipParentheses; /** - * @author Maxim.Medvedev + * Created by Max Medvedev on 10/29/13 */ public abstract class GrIntroduceHandlerBase implements RefactoringActionHandler { private static final Logger LOG = Logger.getInstance(GrIntroduceHandlerBase.class); @@ -144,15 +142,8 @@ public abstract class GrIntroduceHandlerBase occurrenceMarkers, - RangeMarker varRangeMarker, - @Nullable RangeMarker expressionRangeMarker, - @Nullable RangeMarker stringPartRangeMarker); - - protected abstract Settings getSettingsForInplace(GrIntroduceContext context, OccurrencesChooser.ReplaceChoice choice); + protected abstract GrAbstractInplaceIntroducer getIntroducer(@NotNull GrIntroduceContext context, + OccurrencesChooser.ReplaceChoice choice); public static Map> fillChoice(GrIntroduceContext context) { HashMap> map = ContainerUtil.newLinkedHashMap(); @@ -296,7 +287,8 @@ public abstract class GrIntroduceHandlerBase callback, Editor editor); public GrIntroduceContext getContext(@NotNull Project project, - @NotNull Editor editor, - @Nullable GrExpression expression, - @Nullable GrVariable variable, - @Nullable StringPartInfo stringPart, - @NotNull PsiElement scope) { + @NotNull Editor editor, + @Nullable GrExpression expression, + @Nullable GrVariable variable, + @Nullable StringPartInfo stringPart, + @NotNull PsiElement scope) { if (variable != null) { final List list = Collections.synchronizedList(new ArrayList()); ReferencesSearch.search(variable, new LocalSearchScope(scope)).forEach(new Processor() { @@ -348,48 +340,6 @@ public abstract class GrIntroduceHandlerBase callback = new Pass() { - @Override - public void pass(final OccurrencesChooser.ReplaceChoice choice) { - - final Settings settings = isInplace ? getSettingsForInplace(context, choice) : showDialog(context); - if (settings == null) return; - - CommandProcessor.getInstance().executeCommand(project, new Runnable() { - public void run() { - List occurrences = ContainerUtil.newArrayList(); - Document document = editor.getDocument(); - for (PsiElement element : context.getOccurrences()) { - occurrences.add(createRange(document, element)); - } - RangeMarker expressionRangeMarker = createRange(document, context.getExpression()); - RangeMarker stringPartRangeMarker = createRange(document, context.getStringPart()); - RangeMarker varRangeMarker = createRange(document, context.getVar()); - - SmartPsiElementPointer pointer = - ApplicationManager.getApplication().runWriteAction(new Computable>() { - @Override - public SmartPsiElementPointer compute() { - GrVariable var = runRefactoring(context, settings); - return var != null - ? SmartPointerManager.getInstance(context.getProject()).createSmartPsiElementPointer(var) - : null; - } - }); - GrVariable var = pointer != null ? pointer.getElement() : null; - - if (isInplace && var != null) { - GrInplaceIntroducer introducer = getIntroducer(var, context, settings, occurrences, varRangeMarker, expressionRangeMarker, stringPartRangeMarker); - LinkedHashSet suggestions = introducer.suggestNames(context); - PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); - introducer.performInplaceRefactoring(suggestions); - } - } - }, getRefactoringName(), getRefactoringName()); - } - }; - if (isInplace(context.getEditor(), context.getPlace())) { Map> occurrencesMap = fillChoice(context); new OccurrencesChooser(editor) { @@ -405,17 +355,28 @@ public abstract class GrIntroduceHandlerBase() { + @Override + public void pass(final OccurrencesChooser.ReplaceChoice choice) { + getIntroducer(context, choice).startInplaceIntroduceTemplate(); + } + }, occurrencesMap); } else { - callback.pass(null); + final Settings settings = showDialog(context); + if (settings == null) return false; + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + runRefactoring(context, settings); + } + }); } return true; } catch (GrRefactoringError e) { - CommonRefactoringUtil - .showErrorHint(project, editor, RefactoringBundle.getCannotRefactorMessage(e.getMessage()), getRefactoringName(), getHelpID()); + CommonRefactoringUtil.showErrorHint(project, editor, RefactoringBundle.getCannotRefactorMessage(e.getMessage()), getRefactoringName(), getHelpID()); return false; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceConstantIntroducer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceConstantIntroducer.java index ff5a264036fb..df6623b42a88 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceConstantIntroducer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceConstantIntroducer.java @@ -15,127 +15,118 @@ */ package org.jetbrains.plugins.groovy.refactoring.introduce.constant; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.psi.*; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtilCore; -import com.intellij.util.containers.ContainerUtil; +import com.intellij.refactoring.introduce.inplace.OccurrencesChooser; +import com.intellij.refactoring.introduceField.IntroduceConstantHandler; +import com.intellij.ui.components.JBCheckBox; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil; -import org.jetbrains.plugins.groovy.refactoring.introduce.GrInplaceIntroducer; +import org.jetbrains.plugins.groovy.refactoring.introduce.GrAbstractInplaceIntroducer; import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext; -import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContextImpl; +import org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo; import org.jetbrains.plugins.groovy.refactoring.introduce.field.GroovyInplaceFieldValidator; import javax.swing.*; -import java.util.LinkedHashSet; -import java.util.List; /** * Created by Max Medvedev on 8/29/13 */ -public class GrInplaceConstantIntroducer extends GrInplaceIntroducer { +public class GrInplaceConstantIntroducer extends GrAbstractInplaceIntroducer { private final GrInplaceIntroduceConstantPanel myPanel; private final GrIntroduceContext myContext; - private final RangeMarker myExpressionRangeMarker; - private final RangeMarker myStringPartRangeMarker; - private final boolean myReplaceAll; + private String[] mySuggestedNames; - public GrInplaceConstantIntroducer(GrVariable var, - GrIntroduceContext context, - List occurrences, - boolean replaceAllOccurrences, - RangeMarker expressionRangeMarker, - RangeMarker stringPartRangeMarker) { - super(var, context.getEditor(), context.getProject(), GrIntroduceConstantHandler.REFACTORING_NAME, occurrences, context.getPlace()); + public GrInplaceConstantIntroducer(GrIntroduceContext context, OccurrencesChooser.ReplaceChoice choice) { + super(IntroduceConstantHandler.REFACTORING_NAME, choice, context); myContext = context; - myReplaceAll = replaceAllOccurrences; - myExpressionRangeMarker = expressionRangeMarker; - myStringPartRangeMarker = stringPartRangeMarker; myPanel = new GrInplaceIntroduceConstantPanel(); + + mySuggestedNames = GroovyNameSuggestionUtil.suggestVariableNames(context.getExpression(), new GroovyInplaceFieldValidator(context), + true); } @Override - public LinkedHashSet suggestNames(GrIntroduceContext context) { - return ContainerUtil.newLinkedHashSet(GroovyNameSuggestionUtil.suggestVariableNames( - context.getExpression(), - new GroovyInplaceFieldValidator(context), - getVariable().hasModifierProperty(PsiModifier.STATIC)) - ); + protected String getActionName() { + return null; } @Override - protected void moveOffsetAfter(boolean success) { - if (success) { - final GrVariable field = getVariable(); - assert field != null; - GrIntroduceConstantProcessor processor = new GrIntroduceConstantProcessor(generateContext(), generateSettings()) { - @Override - protected GrVariableDeclaration addDeclaration(PsiClass targetClass, GrVariableDeclaration declaration) { - return (GrVariableDeclaration)field.getParent(); - } - - @Override - protected boolean checkErrors(@NotNull PsiClass targetClass) { - return false; - } - }; - processor.run(); - } - super.moveOffsetAfter(success); - } - - private GrIntroduceContext generateContext() { - final List occurrenceMarkers = getOccurrenceMarkers(); - - List occurrences = ContainerUtil.newArrayList(); - for (RangeMarker marker : occurrenceMarkers) { - ContainerUtil.addIfNotNull(occurrences, findExpression(marker)); - } - - GrExpression expr = null; - if (myExpressionRangeMarker != null) expr = findExpression(myExpressionRangeMarker); - if (myStringPartRangeMarker != null) { - expr = findExpressionFromStringPartMarker(myStringPartRangeMarker); - occurrences.add(expr); - } - - return new GrIntroduceContextImpl(myContext.getProject(), myContext.getEditor(), expr, null, null, PsiUtilCore.toPsiElementArray( - occurrences), myContext.getScope()); + protected String[] suggestNames(boolean replaceAll, @Nullable GrVariable variable) { + return mySuggestedNames; } @Nullable - private GrExpression findExpressionFromStringPartMarker(RangeMarker marker) { - PsiFile file = PsiDocumentManager.getInstance(myContext.getProject()).getPsiFile(marker.getDocument()); - if (file == null) return null; - PsiElement leaf = file.findElementAt(marker.getStartOffset()); - GrBinaryExpression binary = PsiTreeUtil.getParentOfType(leaf, GrBinaryExpression.class); - if (binary != null) { - return binary.getRightOperand(); + @Override + protected JComponent getComponent() { + return myPanel.getRootPane(); + } + + @Override + protected void saveSettings(@NotNull GrVariable variable) { + + } + + @Override + protected GrVariable runRefactoring(GrIntroduceContext context, GrIntroduceConstantSettings settings, boolean processUsages) { + if (processUsages) { + return new GrIntroduceConstantProcessor(context, settings).run(); + } + else { + PsiElement scope = context.getScope(); + return new GrIntroduceConstantProcessor(context, settings).addDeclaration(scope instanceof GroovyFileBase ? ((GroovyFileBase)scope).getScriptClass() : (PsiClass)scope).getVariables()[0]; } - return null; } @Nullable - private GrExpression findExpression(@NotNull RangeMarker marker) { - PsiFile file = PsiDocumentManager.getInstance(myContext.getProject()).getPsiFile(marker.getDocument()); - if (file == null) return null; - PsiElement leaf = file.findElementAt(marker.getStartOffset()); - if (leaf != null && leaf.getParent() instanceof GrReferenceExpression) { - return (GrExpression)leaf.getParent(); - } - return null; + @Override + protected GrIntroduceConstantSettings getInitialSettingsForInplace(@NotNull final GrIntroduceContext context, + @NotNull final OccurrencesChooser.ReplaceChoice choice, + final String[] names) { + return new GrIntroduceConstantSettings() { + @Override + public String getVisibilityModifier() { + return PsiModifier.PUBLIC; + } + + @Nullable + @Override + public PsiClass getTargetClass() { + return (PsiClass)context.getScope(); + } + + @Nullable + @Override + public String getName() { + return names[0]; + } + + @Override + public boolean replaceAllOccurrences() { + return isReplaceAllOccurrences(); + } + + @Nullable + @Override + public PsiType getSelectedType() { + GrExpression expression = context.getExpression(); + GrVariable var = context.getVar(); + StringPartInfo stringPart = context.getStringPart(); + return var != null ? var.getDeclaredType() : + expression != null ? expression.getType() : + stringPart != null ? stringPart.getLiteral().getType() : + null; + } + }; } - private GrIntroduceConstantSettings generateSettings() { + @Override + protected GrIntroduceConstantSettings getSettings() { return new GrIntroduceConstantSettings() { @Override public String getVisibilityModifier() { @@ -145,18 +136,18 @@ public class GrInplaceConstantIntroducer extends GrInplaceIntroducer { @Nullable @Override public String getName() { - return getVariable().getName(); + return getInputName(); } @Override public boolean replaceAllOccurrences() { - return myReplaceAll; + return isReplaceAllOccurrences(); } @Nullable @Override public PsiType getSelectedType() { - return getVariable().getDeclaredType(); + return GrInplaceConstantIntroducer.this.getSelectedType(); } @Nullable @@ -167,17 +158,30 @@ public class GrInplaceConstantIntroducer extends GrInplaceIntroducer { }; } - @Nullable - @Override - protected JComponent getComponent() { - //return myPanel.getRootPane(); - return null; - } - @Nullable @Override protected PsiElement checkLocalScope() { - return getVariable().getContainingFile(); + return ((PsiField)getVariable()).getContainingClass(); } + /** + * Created by Max Medvedev on 8/29/13 + */ + public class GrInplaceIntroduceConstantPanel { + private JBCheckBox myMoveToAnotherClassJBCheckBox; + private JPanel myRootPane; + private JComponent myPreview; + + public boolean isMoveToAnotherClass() { + return myMoveToAnotherClassJBCheckBox.isSelected(); + } + + public JComponent getRootPane() { + return myRootPane; + } + + private void createUIComponents() { + myPreview = getPreviewComponent(); + } + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceIntroduceConstantPanel.form b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceIntroduceConstantPanel.form index da9c8bc90939..10e87c6fcd89 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceIntroduceConstantPanel.form +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceIntroduceConstantPanel.form @@ -1,6 +1,6 @@ -
- + + @@ -10,17 +10,24 @@ - + - + + + + + + + + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceIntroduceConstantPanel.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceIntroduceConstantPanel.java deleted file mode 100644 index 5bd7e5bf48df..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrInplaceIntroduceConstantPanel.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2000-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.plugins.groovy.refactoring.introduce.constant; - -import com.intellij.ui.components.JBCheckBox; - -import javax.swing.*; - -/** - * Created by Max Medvedev on 8/29/13 - */ -public class GrInplaceIntroduceConstantPanel { - private JBCheckBox myMoveToAnotherClassJBCheckBox; - private JPanel myRootPane; - - public boolean isMoveToAnotherClass() { - return myMoveToAnotherClassJBCheckBox.isSelected(); - } - - public JComponent getRootPane() { - return myRootPane; - } -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantHandler.java index 926c51eb5b77..9d03af8b5a78 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantHandler.java @@ -15,7 +15,6 @@ */ package org.jetbrains.plugins.groovy.refactoring.introduce.constant; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.HelpID; @@ -27,16 +26,11 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.refactoring.GrRefactoringError; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; import org.jetbrains.plugins.groovy.refactoring.introduce.*; -import org.jetbrains.plugins.groovy.refactoring.introduce.field.GrFieldNameSuggester; -import org.jetbrains.plugins.groovy.refactoring.introduce.field.GroovyInplaceFieldValidator; - -import java.util.List; /** * @author Maxim.Medvedev @@ -99,65 +93,9 @@ public class GrIntroduceConstantHandler extends GrIntroduceFieldHandlerBase occurrenceMarkers, - RangeMarker varRangeMarker, RangeMarker expressionRangeMarker, - RangeMarker stringPartRangeMarker) { - if (varRangeMarker != null) { - context.getEditor().getCaretModel().moveToOffset(var.getNameIdentifierGroovy().getTextRange().getStartOffset()); - } - else if (expressionRangeMarker != null) { - context.getEditor().getCaretModel().moveToOffset(expressionRangeMarker.getStartOffset()); - } - else if (stringPartRangeMarker != null) { - int offset = stringPartRangeMarker.getStartOffset(); - PsiElement at = var.getContainingFile().findElementAt(offset); - GrExpression ref = PsiTreeUtil.getParentOfType(at, GrBinaryExpression.class).getRightOperand(); - context.getEditor().getCaretModel().moveToOffset(ref.getTextRange().getStartOffset()); - } - - return new GrInplaceConstantIntroducer(var, context, occurrenceMarkers, settings.replaceAllOccurrences(), expressionRangeMarker, stringPartRangeMarker); - } - - @Override - protected GrIntroduceConstantSettings getSettingsForInplace(final GrIntroduceContext context, final OccurrencesChooser.ReplaceChoice choice) { - return new GrIntroduceConstantSettings() { - @Override - public String getVisibilityModifier() { - return PsiModifier.PUBLIC; - } - - @Nullable - @Override - public PsiClass getTargetClass() { - return (PsiClass)context.getScope(); - } - - @Nullable - @Override - public String getName() { - return new GrFieldNameSuggester(context, new GroovyInplaceFieldValidator(context), false).suggestNames().iterator().next(); - } - - @Override - public boolean replaceAllOccurrences() { - return choice == OccurrencesChooser.ReplaceChoice.ALL; - } - - @Nullable - @Override - public PsiType getSelectedType() { - GrExpression expression = context.getExpression(); - GrVariable var = context.getVar(); - StringPartInfo stringPart = context.getStringPart(); - return var != null ? var.getDeclaredType() : - expression != null ? expression.getType() : - stringPart != null ? stringPart.getLiteral().getType() : - null; - } - }; + protected GrAbstractInplaceIntroducer getIntroducer(@NotNull GrIntroduceContext context, + OccurrencesChooser.ReplaceChoice choice) { + return new GrInplaceConstantIntroducer(context, choice); } private static class ConstantChecker extends GroovyRecursiveElementVisitor { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantProcessor.java index 2e2f0007350f..bb13241a8d9e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantProcessor.java @@ -69,8 +69,7 @@ public class GrIntroduceConstantProcessor { return null; } - final GrVariableDeclaration rawDeclaration = createField(targetClass); - final GrVariableDeclaration declaration = addDeclaration(targetClass, rawDeclaration); + final GrVariableDeclaration declaration = addDeclaration(targetClass); final GrField field = (GrField)declaration.getVariables()[0]; if (context.getVar() != null) { @@ -102,7 +101,8 @@ public class GrIntroduceConstantProcessor { context.getEditor().getSelectionModel().removeSelection(); } - protected GrVariableDeclaration addDeclaration(PsiClass targetClass, GrVariableDeclaration declaration) { + protected GrVariableDeclaration addDeclaration(PsiClass targetClass) { + GrVariableDeclaration declaration = createField(targetClass); final GrVariableDeclaration added; if (targetClass instanceof GrEnumTypeDefinition) { final GrEnumConstantList enumConstants = ((GrEnumTypeDefinition)targetClass).getEnumConstantList(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceFieldIntroducer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceFieldIntroducer.java index c37d13ddd471..58d907e23f0e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceFieldIntroducer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceFieldIntroducer.java @@ -17,140 +17,133 @@ package org.jetbrains.plugins.groovy.refactoring.introduce.field; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.project.Project; import com.intellij.psi.*; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtilCore; import com.intellij.refactoring.introduce.inplace.KeyboardComboSwitcher; +import com.intellij.refactoring.introduce.inplace.OccurrencesChooser; import com.intellij.refactoring.introduceField.IntroduceFieldHandler; import com.intellij.ui.NonFocusableCheckBox; -import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil; +import org.jetbrains.plugins.groovy.refactoring.introduce.GrAbstractInplaceIntroducer; import org.jetbrains.plugins.groovy.refactoring.introduce.GrFinalListener; -import org.jetbrains.plugins.groovy.refactoring.introduce.GrInplaceIntroducer; import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext; -import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContextImpl; +import org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.EnumSet; -import java.util.LinkedHashSet; -import java.util.List; /** * @author Max Medvedev */ -public class GrInplaceFieldIntroducer extends GrInplaceIntroducer { - private final GrInplaceIntroduceFieldPanel myPanel; - private final GrIntroduceContext myContext; - private final RangeMarker myExpressionRangeMarker; - private final RangeMarker myStringPartRangeMarker; - private final GrExpression myInitializer; +public class GrInplaceFieldIntroducer extends GrAbstractInplaceIntroducer { + private GrInplaceIntroduceFieldPanel myPanel; private final GrFinalListener finalListener; - private final boolean myReplaceAll; + private String[] mySuggestedNames; + private boolean myIsStatic; @Nullable @Override protected PsiElement checkLocalScope() { - return getVariable().getContainingFile(); + return ((PsiField)getVariable()).getContainingClass(); } - public GrInplaceFieldIntroducer(GrVariable var, - GrIntroduceContext context, - List occurrences, - boolean replaceAll, - @Nullable RangeMarker expressionRangeMarker, - @Nullable RangeMarker stringPartRangeMarker, - GrExpression initializer) { - super(var, context.getEditor(), context.getProject(), IntroduceFieldHandler.REFACTORING_NAME, occurrences, context.getPlace()); - - myContext = context; - myReplaceAll = replaceAll; - myExpressionRangeMarker = expressionRangeMarker; - myStringPartRangeMarker = stringPartRangeMarker; - myInitializer = initializer; - - myPanel = new GrInplaceIntroduceFieldPanel(context.getProject(), - GrIntroduceFieldHandler.getApplicableInitPlaces(context, replaceAll)); + public GrInplaceFieldIntroducer(GrIntroduceContext context, OccurrencesChooser.ReplaceChoice choice) { + super(IntroduceFieldHandler.REFACTORING_NAME, choice, context); finalListener = new GrFinalListener(myEditor); + + mySuggestedNames = GroovyNameSuggestionUtil.suggestVariableNames(context.getExpression(), new GroovyInplaceFieldValidator(getContext()), false); } @Override - protected void moveOffsetAfter(boolean success) { - if (success) { - final GrVariable field = getVariable(); - assert field != null; - GrIntroduceFieldProcessor processor = new GrIntroduceFieldProcessor(generateContext(), generateSettings(), false) { - @NotNull - @Override - protected GrExpression getInitializer() { - return myInitializer; - } - - @NotNull - @Override - protected GrVariableDeclaration insertField(@NotNull PsiClass targetClass, @NotNull GrVariableDeclaration declaration) { - return (GrVariableDeclaration)field.getParent(); - } - }; - processor.run(); - } - super.moveOffsetAfter(success); - } - - private GrIntroduceContext generateContext() { - final List occurrenceMarkers = getOccurrenceMarkers(); - - List occurrences = ContainerUtil.newArrayList(); - for (RangeMarker marker : occurrenceMarkers) { - ContainerUtil.addIfNotNull(occurrences, findExpression(marker)); - } - - GrExpression expr = null; - if (myExpressionRangeMarker != null) expr = findExpression(myExpressionRangeMarker); - if (myStringPartRangeMarker != null) { - expr = findExpressionFromStringPartMarker(myStringPartRangeMarker); - occurrences.add(expr); - } - - return new GrIntroduceContextImpl(myContext.getProject(), myContext.getEditor(), expr, null, null, PsiUtilCore.toPsiElementArray( - occurrences), myContext.getScope()); + protected GrVariable runRefactoring(GrIntroduceContext context, GrIntroduceFieldSettings settings, boolean processUsages) { + GrIntroduceFieldProcessor processor = new GrIntroduceFieldProcessor(context, settings); + return processUsages ? processor.run() + : processor.insertField((PsiClass)context.getScope()).getVariables()[0]; } @Nullable - private GrExpression findExpressionFromStringPartMarker(RangeMarker marker) { - PsiFile file = PsiDocumentManager.getInstance(myContext.getProject()).getPsiFile(marker.getDocument()); - if (file == null) return null; - PsiElement leaf = file.findElementAt(marker.getStartOffset()); - GrBinaryExpression binary = PsiTreeUtil.getParentOfType(leaf, GrBinaryExpression.class); - if (binary != null) { - return binary.getRightOperand(); - } - return null; + @Override + protected GrIntroduceFieldSettings getInitialSettingsForInplace(@NotNull final GrIntroduceContext context, + @NotNull final OccurrencesChooser.ReplaceChoice choice, + final String[] names) { + return new GrIntroduceFieldSettings() { + @Override + public boolean declareFinal() { + return false; + } + + @Override + public Init initializeIn() { + return Init.FIELD_DECLARATION; + } + + @Override + public String getVisibilityModifier() { + return PsiModifier.PRIVATE; + } + + @Override + public boolean isStatic() { + boolean hasInstanceInScope = true; + PsiClass clazz = (PsiClass)context.getScope(); + if (replaceAllOccurrences()) { + for (PsiElement occurrence : context.getOccurrences()) { + if (!PsiUtil.hasEnclosingInstanceInScope(clazz, occurrence, false)) { + hasInstanceInScope = false; + break; + } + } + } + else if (context.getExpression() != null) { + hasInstanceInScope = PsiUtil.hasEnclosingInstanceInScope(clazz, context.getExpression(), false); + } + else if (context.getStringPart() != null) { + hasInstanceInScope = PsiUtil.hasEnclosingInstanceInScope(clazz, context.getStringPart().getLiteral(), false); + } + + return !hasInstanceInScope; + } + + @Override + public boolean removeLocalVar() { + return context.getVar() != null; + } + + @Nullable + @Override + public String getName() { + return names[0]; + } + + @Override + public boolean replaceAllOccurrences() { + return context.getVar() != null || choice == OccurrencesChooser.ReplaceChoice.ALL; + } + + @Nullable + @Override + public PsiType getSelectedType() { + GrExpression expression = context.getExpression(); + GrVariable var = context.getVar(); + StringPartInfo stringPart = context.getStringPart(); + return var != null ? var.getDeclaredType() : + expression != null ? expression.getType() : + stringPart != null ? stringPart.getLiteral().getType() : + null; + } + }; } - @Nullable - private GrExpression findExpression(@NotNull RangeMarker marker) { - PsiFile file = PsiDocumentManager.getInstance(myContext.getProject()).getPsiFile(marker.getDocument()); - if (file == null) return null; - PsiElement leaf = file.findElementAt(marker.getStartOffset()); - if (leaf != null && leaf.getParent() instanceof GrReferenceExpression) { - return (GrExpression)leaf.getParent(); - } - return null; - } - - private GrIntroduceFieldSettings generateSettings() { + @Override + protected GrIntroduceFieldSettings getSettings() { return new GrIntroduceFieldSettings() { @Override public boolean declareFinal() { @@ -169,7 +162,7 @@ public class GrInplaceFieldIntroducer extends GrInplaceIntroducer { @Override public boolean isStatic() { - return getVariable().hasModifierProperty(PsiModifier.STATIC); + return myIsStatic; } @Override @@ -180,39 +173,57 @@ public class GrInplaceFieldIntroducer extends GrInplaceIntroducer { @Nullable @Override public String getName() { - return getVariable().getName(); + return getInputName(); } @Override public boolean replaceAllOccurrences() { - return myReplaceAll; + return isReplaceAllOccurrences(); } @Nullable @Override public PsiType getSelectedType() { - return getVariable().getDeclaredType(); + return GrInplaceFieldIntroducer.this.getSelectedType(); } }; } + @Override + protected String getActionName() { + return IntroduceFieldHandler.REFACTORING_NAME; + } + + @Override + protected String[] suggestNames(boolean replaceAll, @Nullable GrVariable variable) { + return mySuggestedNames; + } + + @Override + protected void saveSettings(@NotNull GrVariable variable) { + + } + + @Override + protected void restoreState(GrVariable psiField) { + myIsStatic = psiField.hasModifierProperty(PsiModifier.STATIC); + + super.restoreState(psiField); + } + @Nullable @Override protected JComponent getComponent() { + myPanel = new GrInplaceIntroduceFieldPanel(myProject, GrIntroduceFieldHandler.getApplicableInitPlaces(getContext(), isReplaceAllOccurrences())); return myPanel.getRootPane(); } - @Override - public LinkedHashSet suggestNames(GrIntroduceContext context) { - return ContainerUtil.newLinkedHashSet( - GroovyNameSuggestionUtil.suggestVariableNames(myInitializer, new GroovyInplaceFieldValidator(context), false)); - } - public class GrInplaceIntroduceFieldPanel { private final Project myProject; private JPanel myRootPane; private JComboBox myInitCB; private NonFocusableCheckBox myDeclareFinalCB; + private JComponent myPreview; public GrInplaceIntroduceFieldPanel(Project project, EnumSet initPlaces) { myProject = project; @@ -251,5 +262,9 @@ public class GrInplaceFieldIntroducer extends GrInplaceIntroducer { public boolean isFinal() { return myDeclareFinalCB.isSelected(); } + + private void createUIComponents() { + myPreview = getPreviewComponent(); + } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceIntroduceFieldPanel.form b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceIntroduceFieldPanel.form index 96f32e533680..c75e58c49327 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceIntroduceFieldPanel.form +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceIntroduceFieldPanel.form @@ -1,9 +1,9 @@
- + - + @@ -11,7 +11,7 @@ - + @@ -35,13 +35,18 @@ - + + + + + + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java index 0211ee378a4c..a21dbe17f654 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java @@ -16,25 +16,21 @@ package org.jetbrains.plugins.groovy.refactoring.introduce.field; import com.intellij.codeInsight.TestFrameworks; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiModifier; -import com.intellij.psi.PsiType; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.introduce.inplace.OccurrencesChooser; import com.intellij.refactoring.introduceField.IntroduceFieldHandler; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember; +import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.refactoring.GrRefactoringError; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; @@ -100,133 +96,39 @@ public class GrIntroduceFieldHandler extends GrIntroduceFieldHandlerBase occurrenceMarkers, - @Nullable RangeMarker varRangeMarker, - @Nullable RangeMarker expressionRangeMarker, - @Nullable RangeMarker stringPartRangeMarker) { - if (varRangeMarker != null) { - context.getEditor().getCaretModel().moveToOffset(var.getNameIdentifierGroovy().getTextRange().getStartOffset()); - } - else if (expressionRangeMarker != null) { - context.getEditor().getCaretModel().moveToOffset(expressionRangeMarker.getStartOffset()); - } - else if (stringPartRangeMarker != null) { - int offset = stringPartRangeMarker.getStartOffset(); - PsiElement at = var.getContainingFile().findElementAt(offset); - GrExpression ref = PsiTreeUtil.getParentOfType(at, GrBinaryExpression.class).getRightOperand(); - context.getEditor().getCaretModel().moveToOffset(ref.getTextRange().getStartOffset()); - } - GrExpression initializer = - GroovyPsiElementFactory.getInstance(context.getProject()).createExpressionFromText(var.getInitializerGroovy().getText()); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - var.setInitializerGroovy(null); - } - }); - return new GrInplaceFieldIntroducer(var, context, occurrenceMarkers, settings.replaceAllOccurrences(), expressionRangeMarker, - stringPartRangeMarker, initializer); + @Override + protected GrAbstractInplaceIntroducer getIntroducer(@NotNull GrIntroduceContext context, + OccurrencesChooser.ReplaceChoice choice) { + return new GrInplaceFieldIntroducer(context, choice); } static EnumSet getApplicableInitPlaces(GrIntroduceContext context, boolean replaceAll) { - EnumSet result = EnumSet.of(GrIntroduceFieldSettings.Init.FIELD_DECLARATION, - GrIntroduceFieldSettings.Init.CONSTRUCTOR); + EnumSet result = EnumSet.of(GrIntroduceFieldSettings.Init.FIELD_DECLARATION); + if (!(context.getScope() instanceof GroovyScriptClass || context.getScope() instanceof GroovyFileBase)) { + result.add(GrIntroduceFieldSettings.Init.CONSTRUCTOR); + } - GrTypeDefinition clazz = (GrTypeDefinition)context.getScope(); + PsiElement scope = context.getScope(); if (replaceAll) { - PsiElement anchor = GrIntroduceHandlerBase.findAnchor(context.getOccurrences(), clazz); + PsiElement anchor = GrIntroduceHandlerBase.findAnchor(context.getOccurrences(), scope); if (anchor != null) { result.add(GrIntroduceFieldSettings.Init.CUR_METHOD); } } - if (TestFrameworks.getInstance().isTestClass(clazz)) { + if (scope instanceof GrTypeDefinition && TestFrameworks.getInstance().isTestClass((PsiClass)scope)) { result.add(GrIntroduceFieldSettings.Init.SETUP_METHOD); } return result; } - @Override - protected GrIntroduceFieldSettings getSettingsForInplace(final GrIntroduceContext context, final OccurrencesChooser.ReplaceChoice choice) { - return new GrIntroduceFieldSettings() { - @Override - public boolean declareFinal() { - return false; - } - - @Override - public Init initializeIn() { - return Init.FIELD_DECLARATION; - } - - @Override - public String getVisibilityModifier() { - return PsiModifier.PRIVATE; - } - - @Override - public boolean isStatic() { - boolean hasInstanceInScope = true; - PsiClass clazz = (PsiClass)context.getScope(); - if (replaceAllOccurrences()) { - for (PsiElement occurrence : context.getOccurrences()) { - if (!PsiUtil.hasEnclosingInstanceInScope(clazz, occurrence, false)) { - hasInstanceInScope = false; - break; - } - } - } - else if (context.getExpression() != null) { - hasInstanceInScope = PsiUtil.hasEnclosingInstanceInScope(clazz, context.getExpression(), false); - } - else if (context.getStringPart() != null) { - hasInstanceInScope = PsiUtil.hasEnclosingInstanceInScope(clazz, context.getStringPart().getLiteral(), false); - } - - return !hasInstanceInScope; - } - - @Override - public boolean removeLocalVar() { - return context.getVar() != null; - } - - @Nullable - @Override - public String getName() { - return new GrFieldNameSuggester(context, new GroovyInplaceFieldValidator(context), false).suggestNames().iterator().next(); - } - - @Override - public boolean replaceAllOccurrences() { - return context.getVar() != null || choice == OccurrencesChooser.ReplaceChoice.ALL; - } - - @Nullable - @Override - public PsiType getSelectedType() { - GrExpression expression = context.getExpression(); - GrVariable var = context.getVar(); - StringPartInfo stringPart = context.getStringPart(); - return var != null ? var.getDeclaredType() : - expression != null ? expression.getType() : - stringPart != null ? stringPart.getLiteral().getType() : - null; - } - }; - } - @NotNull @Override protected PsiElement[] findOccurrences(@NotNull GrExpression expression, @NotNull PsiElement scope) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldProcessor.java index 81da87ba01c7..5331e4388bad 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldProcessor.java @@ -25,8 +25,10 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster; import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier; import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; @@ -62,19 +64,19 @@ public class GrIntroduceFieldProcessor { private final GrIntroduceContext context; private final GrIntroduceFieldSettings settings; - private boolean myForInplacePrepare; - public GrIntroduceFieldProcessor(@NotNull GrIntroduceContext context, @NotNull GrIntroduceFieldSettings settings, boolean forInplacePrepare) { + public GrIntroduceFieldProcessor(@NotNull GrIntroduceContext context, + @NotNull GrIntroduceFieldSettings settings) { this.context = context; this.settings = settings; - myForInplacePrepare = forInplacePrepare; } public GrVariable run() { - final PsiClass targetClass = (PsiClass)context.getScope(); + PsiElement scope = context.getScope(); + final PsiClass targetClass = scope instanceof GroovyFileBase ? ((GroovyFileBase)scope).getScriptClass() : (PsiClass)scope; if (targetClass == null) return null; - final GrVariableDeclaration declaration = insertField(targetClass, createField()); + final GrVariableDeclaration declaration = insertField(targetClass); final GrVariable field = declaration.getVariables()[0]; switch (settings.initializeIn()) { @@ -119,7 +121,7 @@ public class GrIntroduceFieldProcessor { else { final GrExpression expression = context.getExpression(); assert expression != null; - if (!myForInplacePrepare && PsiUtil.isExpressionStatement(expression)) { + if (PsiUtil.isExpressionStatement(expression)) { expression.delete(); } else { @@ -135,7 +137,8 @@ public class GrIntroduceFieldProcessor { } @NotNull - protected GrVariableDeclaration insertField(@NotNull PsiClass targetClass, @NotNull GrVariableDeclaration declaration) { + protected GrVariableDeclaration insertField(@NotNull PsiClass targetClass) { + GrVariableDeclaration declaration = createField(targetClass); if (targetClass instanceof GrEnumTypeDefinition) { final GrEnumConstantList enumConstants = ((GrEnumTypeDefinition)targetClass).getEnumConstantList(); return (GrVariableDeclaration)targetClass.addAfter(declaration, enumConstants); @@ -304,7 +307,7 @@ public class GrIntroduceFieldProcessor { } if (replaced instanceof GrQualifiedReference) { - org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster.shortenReference((GrQualifiedReference)replaced); + GrReferenceAdjuster.shortenReference((GrQualifiedReference)replaced); } if (isOriginal) { updateCaretPosition(replaced); @@ -326,13 +329,13 @@ public class GrIntroduceFieldProcessor { return GroovyPsiElementFactory.getInstance(place.getProject()).createReferenceExpressionFromText(refText, place); } - private GrVariableDeclaration createField() { + private GrVariableDeclaration createField(PsiClass targetClass) { final String name = settings.getName(); final PsiType type = settings.getSelectedType(); final String modifier = settings.getVisibilityModifier(); List modifiers = new ArrayList(); - if (context.getScope() instanceof GroovyScriptClass) { + if (targetClass instanceof GroovyScriptClass) { modifiers.add("@" + GroovyCommonClassNames.GROOVY_TRANSFORM_FIELD); } if (settings.isStatic()) modifiers.add(PsiModifier.STATIC); @@ -341,7 +344,7 @@ public class GrIntroduceFieldProcessor { final String[] arr_modifiers = ArrayUtil.toStringArray(modifiers); final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(context.getProject()); - if (context.getScope() instanceof GroovyScriptClass) { + if (targetClass instanceof GroovyScriptClass) { return factory.createVariableDeclaration(arr_modifiers, ((GrExpression)null), type, name); } else { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrInplaceVariableIntroducer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrInplaceVariableIntroducer.java index eb19b097c90f..a8732988a2c8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrInplaceVariableIntroducer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrInplaceVariableIntroducer.java @@ -16,25 +16,31 @@ package org.jetbrains.plugins.groovy.refactoring.introduce.variable; import com.intellij.codeInsight.template.TemplateBuilderImpl; +import com.intellij.openapi.actionSystem.Shortcut; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.RangeMarker; -import com.intellij.openapi.project.Project; +import com.intellij.openapi.keymap.Keymap; +import com.intellij.openapi.keymap.KeymapManager; +import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiType; +import com.intellij.refactoring.introduce.inplace.OccurrencesChooser; +import com.intellij.refactoring.util.CanonicalTypes; import com.intellij.ui.NonFocusableCheckBox; -import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SupertypeConstraint; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil; +import org.jetbrains.plugins.groovy.refactoring.introduce.GrAbstractInplaceIntroducer; import org.jetbrains.plugins.groovy.refactoring.introduce.GrFinalListener; -import org.jetbrains.plugins.groovy.refactoring.introduce.GrInplaceIntroducer; import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext; +import org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo; import org.jetbrains.plugins.groovy.settings.GroovyApplicationSettings; import org.jetbrains.plugins.groovy.template.expressions.ChooseTypeExpression; @@ -42,30 +48,40 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.LinkedHashSet; -import java.util.List; /** - * @author Max Medvedev + * Created by Max Medvedev on 10/29/13 */ -public class GrInplaceVariableIntroducer extends GrInplaceIntroducer { +public abstract class GrInplaceVariableIntroducer extends GrAbstractInplaceIntroducer { private JCheckBox myCanBeFinalCb; - public GrInplaceVariableIntroducer(GrVariable elementToRename, - Editor editor, - Project project, - String title, - List occurrences, - @Nullable PsiElement elementToIntroduce) { - super(elementToRename, editor, project, title, occurrences, elementToIntroduce); - } - - @Override - public LinkedHashSet suggestNames(GrIntroduceContext context) { - return ContainerUtil.newLinkedHashSet(GroovyNameSuggestionUtil.suggestVariableNames(getVariable().getInitializerGroovy(), new GroovyVariableValidator(context))); + public GrInplaceVariableIntroducer(String title, + OccurrencesChooser.ReplaceChoice replaceChoice, + GrIntroduceContext context) { + super(title, replaceChoice, context); + setAdvertisementText(getAdvertisementText()); } @Nullable + private static String getAdvertisementText() { + final Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); + final Shortcut[] shortcuts = keymap.getShortcuts("PreviousTemplateVariable"); + if (shortcuts.length > 0) { + return "Press " + KeymapUtil.getShortcutText(shortcuts[0]) + " to change type"; + } + return null; + } + + @Override + protected String getActionName() { + return GrIntroduceVariableHandler.REFACTORING_NAME; + } + + @Override + protected String[] suggestNames(boolean replaceAll, @Nullable GrVariable variable) { + return GroovyNameSuggestionUtil.suggestVariableNames(getContext().getExpression(), new GroovyVariableValidator(getContext())); + } + @Override protected JComponent getComponent() { myCanBeFinalCb = new NonFocusableCheckBox("Declare final"); @@ -91,22 +107,58 @@ public class GrInplaceVariableIntroducer extends GrInplaceIntroducer { panel.setBorder(null); if (myCanBeFinalCb != null) { - panel.add(myCanBeFinalCb, new GridBagConstraints(0, 1, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0)); + panel.add(myCanBeFinalCb, new GridBagConstraints(0, 1, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, + new Insets(5, 5, 5, 5), 0, 0)); } - panel.add(Box.createVerticalBox(), new GridBagConstraints(0, 2, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0,0,0,0), 0,0)); + panel.add(Box.createVerticalBox(), + new GridBagConstraints(0, 2, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); return panel; - } + @Nullable @Override - public void finish(boolean success) { - super.finish(success); + protected GroovyIntroduceVariableSettings getInitialSettingsForInplace(@NotNull final GrIntroduceContext context, + @NotNull final OccurrencesChooser.ReplaceChoice choice, + final String[] names) { + return new GroovyIntroduceVariableSettings() { + private final CanonicalTypes.Type myType; - if (success) { - GroovyApplicationSettings.getInstance().INTRODUCE_LOCAL_SELECT_DEF = getVariable().getDeclaredType() == null; - } + { + GrExpression expression = context.getExpression(); + StringPartInfo stringPart = context.getStringPart(); + GrVariable var = context.getVar(); + PsiType type = expression != null ? expression.getType() : + var != null ? var.getType() : + stringPart != null ? stringPart.getLiteral().getType() : + null; + myType = type != null ? CanonicalTypes.createTypeWrapper(type) : null; + } + + + @Override + public boolean isDeclareFinal() { + return myCanBeFinalCb != null ? myCanBeFinalCb.isSelected() : false; + } + + @Nullable + @Override + public String getName() { + return names[0]; + } + + @Override + public boolean replaceAllOccurrences() { + return choice == OccurrencesChooser.ReplaceChoice.ALL; + } + + @Nullable + @Override + public PsiType getSelectedType() { + return myType != null ? myType.getType(context.getPlace(), context.getPlace().getManager()) : null; + } + }; } @Override @@ -119,4 +171,40 @@ public class GrInplaceVariableIntroducer extends GrInplaceIntroducer { : PsiUtil.findModifierInList(variable.getModifierList(), GrModifier.DEF); builder.replaceElement(element, "Variable_type", typeExpression, true, true); } -} + + protected GroovyIntroduceVariableSettings getSettings() { + return new GroovyIntroduceVariableSettings() { + @Override + public boolean isDeclareFinal() { + return myCanBeFinalCb.isSelected(); + } + + @Nullable + @Override + public String getName() { + return GrInplaceVariableIntroducer.this.getInputName(); + } + + @Override + public boolean replaceAllOccurrences() { + return isReplaceAllOccurrences(); + } + + @Nullable + @Override + public PsiType getSelectedType() { + return GrInplaceVariableIntroducer.this.getSelectedType(); + } + }; + } + + @Override + protected void saveSettings(@NotNull GrVariable variable) { + GroovyApplicationSettings.getInstance().INTRODUCE_LOCAL_SELECT_DEF = variable.getDeclaredType() == null; + } + + @Override + protected int getCaretOffset() { + return getVariable().getNameIdentifierGroovy().getTextRange().getEndOffset(); + } +} \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java index 3d01195b1c4b..9546a20a24a4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java @@ -46,26 +46,26 @@ import java.util.List; /** * @author Max Medvedev */ -public class GrIntroduceLocalVariableProcessor { +public abstract class GrIntroduceLocalVariableProcessor { private static final Logger LOG = Logger.getInstance(GrIntroduceLocalVariableProcessor.class); private final GrIntroduceContext myContext; private final GroovyIntroduceVariableSettings mySettings; + private final boolean myProcessUsages; private final PsiElement[] myOccurrences; private GrExpression myExpression; - private final GrIntroduceVariableHandler myHandler; public GrIntroduceLocalVariableProcessor(@NotNull GrIntroduceContext context, @NotNull GroovyIntroduceVariableSettings settings, @NotNull PsiElement[] occurrences, @NotNull GrExpression expression, - @NotNull GrIntroduceVariableHandler handler) { + boolean processUsages) { myContext = context; mySettings = settings; + myProcessUsages = processUsages; myOccurrences = settings.replaceAllOccurrences() ? occurrences : new PsiElement[]{expression}; myExpression = expression; - myHandler = handler; } @NotNull @@ -75,7 +75,7 @@ public class GrIntroduceLocalVariableProcessor { preprocessOccurrences(); int expressionIndex = ArrayUtilRt.find(myOccurrences, myExpression); - final PsiElement[] replaced = processOccurrences(); + final PsiElement[] replaced = myProcessUsages ? processOccurrences() : myOccurrences; PsiElement replacedExpression = replaced[expressionIndex]; GrStatement anchor = getAnchor(replaced); @@ -84,9 +84,7 @@ public class GrIntroduceLocalVariableProcessor { return insertVariableDefinition(declaration, anchor, replacedExpression); } - private void refreshPositionMarker(PsiElement e) { - myHandler.refreshPositionMarker(myContext.getEditor().getDocument().createRangeMarker(e.getTextRange())); - } + protected abstract void refreshPositionMarker(PsiElement e); private static boolean isControlStatementBranch(GrStatement statement) { return statement.getParent() instanceof GrLoopStatement && statement == ((GrLoopStatement)statement.getParent()).getBody() || diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java index cd2d27b5bdbc..39fac55e7348 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java @@ -13,24 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.jetbrains.plugins.groovy.refactoring.introduce.variable; -import com.intellij.openapi.actionSystem.Shortcut; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; -import com.intellij.openapi.keymap.Keymap; -import com.intellij.openapi.keymap.KeymapManager; -import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.util.Pass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiModifier; -import com.intellij.psi.PsiType; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.introduce.inplace.OccurrencesChooser; -import com.intellij.refactoring.util.CanonicalTypes; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils; import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner; import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; @@ -48,10 +40,8 @@ import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext; import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceHandlerBase; import org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo; -import java.util.List; - /** - * @author ilyas + * Created by Max Medvedev on 10/29/13 */ public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase { public static final String DUMMY_NAME = "________________xxx_________________"; @@ -129,8 +119,7 @@ public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase occurrenceMarkers, - RangeMarker varRangeMarker, RangeMarker expressionRangeMarker, - RangeMarker stringPartRangeMarker) { - context.getEditor().getCaretModel().moveToOffset(var.getTextOffset()); - GrInplaceVariableIntroducer introducer = new GrInplaceVariableIntroducer(var, context.getEditor(), context.getProject(), REFACTORING_NAME, occurrenceMarkers, var); - introducer.setAdvertisementText(getAdvertisementText(var.getDeclaredType() != null)); - - return introducer; - } - - @Nullable - private static String getAdvertisementText(final boolean hasTypeSuggestion) { - final Keymap keymap = KeymapManager.getInstance().getActiveKeymap(); - if (hasTypeSuggestion) { - final Shortcut[] shortcuts = keymap.getShortcuts("PreviousTemplateVariable"); - if (shortcuts.length > 0) { - return "Press " + KeymapUtil.getShortcutText(shortcuts[0]) + " to change type"; - } - } - return null; - } - - @Override - protected GroovyIntroduceVariableSettings getSettingsForInplace(final GrIntroduceContext context, final OccurrencesChooser.ReplaceChoice choice) { - return new GroovyIntroduceVariableSettings() { - private final CanonicalTypes.Type myType; - private final String myName; - - - { - GrExpression expression = context.getExpression(); - StringPartInfo stringPart = context.getStringPart(); - GrVariable var = context.getVar(); - PsiType type = expression != null ? expression.getType() : - var != null ? var.getType() : - stringPart != null ? stringPart.getLiteral().getType() : - null; - myType = type != null ?CanonicalTypes.createTypeWrapper(type) : null; - - myName = new GrVariableNameSuggester(context, new GroovyVariableValidator(context)).suggestNames().iterator().next(); - } - - + protected GrInplaceVariableIntroducer getIntroducer(@NotNull GrIntroduceContext context, OccurrencesChooser.ReplaceChoice choice) { + return new GrInplaceVariableIntroducer(getRefactoringName(), choice, context) { @Override - public boolean isDeclareFinal() { - return false; - } - - @Nullable - @Override - public String getName() { - return myName; - } - - @Override - public boolean replaceAllOccurrences() { - return choice == OccurrencesChooser.ReplaceChoice.ALL; - } - - @Nullable - @Override - public PsiType getSelectedType() { - return myType != null ? myType.getType(context.getPlace(), context.getPlace().getManager()) : null; + protected GrVariable runRefactoring(GrIntroduceContext context, GroovyIntroduceVariableSettings settings, boolean processUsages) { + return processExpression(context, settings, processUsages); } }; } @@ -231,24 +159,31 @@ public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase