diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractInfoHelper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractInfoHelper.java index fde920e2f6f0..85c40082b977 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractInfoHelper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractInfoHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -21,6 +21,7 @@ import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.VariableInfo; import org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo; @@ -52,6 +53,9 @@ public interface ExtractInfoHelper { @Nullable StringPartInfo getStringPartInfo(); + @Nullable + GrVariable getVar(); + boolean hasReturnValue(); String getName(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractInfoHelperBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractInfoHelperBase.java index 24a8cd889b88..67f548774a07 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractInfoHelperBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractInfoHelperBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -21,6 +21,7 @@ import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.VariableInfo; import org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo; @@ -113,6 +114,12 @@ public abstract class ExtractInfoHelperBase implements ExtractInfoHelper { return myInitialInfo.getStringPartInfo(); } + @Nullable + @Override + public GrVariable getVar() { + return myInitialInfo.getVar(); + } + public boolean hasReturnValue() { return myInitialInfo.hasReturnValue(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/GroovyExtractChooser.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/GroovyExtractChooser.java index 6e61c36b3d23..237562151bf7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/GroovyExtractChooser.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/GroovyExtractChooser.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -19,18 +19,22 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.SelectionModel; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.HashSet; +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.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +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.branch.GrReturnStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression; @@ -78,18 +82,35 @@ public class GroovyExtractChooser { SelectionModel selectionModel = editor.getSelectionModel(); PsiDocumentManager.getInstance(project).commitAllDocuments(); - final StringPartInfo stringPart = - StringPartInfo.findStringPart(file, selectionModel.getSelectionStart(), selectionModel.getSelectionEnd()); - + final StringPartInfo stringPart = StringPartInfo.findStringPart(file, selectionModel.getSelectionStart(), selectionModel.getSelectionEnd()); if (stringPart != null) { - return new InitialInfo(new VariableInfo[0], new VariableInfo[0], PsiElement.EMPTY_ARRAY, GrStatement.EMPTY_ARRAY, new ArrayList(), stringPart, project); + return new InitialInfo(new VariableInfo[0], new VariableInfo[0], PsiElement.EMPTY_ARRAY, GrStatement.EMPTY_ARRAY, new ArrayList(), stringPart, project, null); } + GrVariable variable = GrIntroduceHandlerBase.findVariable(file, start, end); + if (variable != null) { + GrExpression initializer = variable.getInitializerGroovy(); + if (initializer != null) { + TextRange range = initializer.getTextRange(); + return buildInfo(project, file, range.getStartOffset(), range.getEndOffset(), forceStatements, selectionModel, variable); + } + } + return buildInfo(project, file, start, end, forceStatements, selectionModel, null); + } + + @NotNull + private static InitialInfo buildInfo(@NotNull Project project, + @NotNull PsiFile file, + int start, + int end, + boolean forceStatements, + @NotNull SelectionModel selectionModel, + @Nullable GrVariable variable) throws GrRefactoringError { PsiElement[] elements = getElementsInOffset(file, start, end, forceStatements); - if (elements.length == 1 && elements[0] instanceof GrExpression) { - selectionModel.setSelection(start, elements[0].getTextRange().getEndOffset()); - } + //if (elements.length == 1 && elements[0] instanceof GrExpression) { + // selectionModel.setSelection(start, elements[0].getTextRange().getEndOffset()); + //} GrStatement[] statements = getStatementsByElements(elements); @@ -171,7 +192,7 @@ public class GroovyExtractChooser { GroovyRefactoringBundle.message("refactoring.is.not.supported.when.return.statement.interrupts.the.execution.flow")); } - return new InitialInfo(inputInfos, outputInfos, elements, statements, returnStatements, null, project); + return new InitialInfo(inputInfos, outputInfos, elements, statements, returnStatements, null, project, variable); } private static boolean isLastStatementOfMethodOrClosure(GrStatement[] statements) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/InitialInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/InitialInfo.java index e50e6d5ed0d1..896f1e2eb0cc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/InitialInfo.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/InitialInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -25,6 +25,7 @@ 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.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.VariableInfo; @@ -47,6 +48,7 @@ public class InitialInfo implements ExtractInfoHelper { private final boolean myHasReturnValue; private final String[] myArgumentNames; private final StringPartInfo myStringPartInfo; + private final GrVariable myVariable; public InitialInfo(VariableInfo[] inputInfos, VariableInfo[] outputInfos, @@ -54,11 +56,12 @@ public class InitialInfo implements ExtractInfoHelper { GrStatement[] statements, ArrayList returnStatements, StringPartInfo stringPartInfo, - Project project) { + Project project, GrVariable variable) { myInnerElements = innerElements; myStatements = statements; myOutputNames = outputInfos; myStringPartInfo = stringPartInfo; + myVariable = variable; myHasReturnValue = ContainerUtil.find(returnStatements, new Condition() { @Override @@ -194,4 +197,10 @@ public class InitialInfo implements ExtractInfoHelper { public StringPartInfo getStringPartInfo() { return myStringPartInfo; } + + @Nullable + @Override + public GrVariable getVar() { + return myVariable; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureHelperImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureHelperImpl.java index d417859edf3a..7b7f9eacf3a5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureHelperImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureHelperImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiType; import gnu.trove.TIntArrayList; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrParametersOwner; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; @@ -135,6 +136,7 @@ public class ExtractClosureHelperImpl extends ExtractInfoHelperBase implements G return myForceReturn; } + @Nullable @Override public GrVariable getVar() { return null; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureProcessorBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureProcessorBase.java index 7359fc08fd15..07ed028704f7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureProcessorBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureProcessorBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -60,7 +60,8 @@ public abstract class ExtractClosureProcessorBase extends BaseRefactoringProcess return EXTRACT_CLOSURE; } - public static GrClosableBlock generateClosure(GrIntroduceParameterSettings helper) { + @NotNull + public static GrClosableBlock generateClosure(@NotNull GrIntroduceParameterSettings helper) { StringBuilder buffer = new StringBuilder(); buffer.append("{ "); 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 c80c447ceddd..be5c2d61bfb4 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 @@ -439,18 +439,7 @@ public abstract class GrIntroduceHandlerBase list = Collections.synchronizedList(new ArrayList()); - ReferencesSearch.search(variable, new LocalSearchScope(scope)).forEach(new Processor() { - @Override - public boolean process(PsiReference psiReference) { - final PsiElement element = psiReference.getElement(); - if (element != null) { - list.add(element); - } - return true; - } - }); - final PsiElement[] occurrences = list.toArray(new PsiElement[list.size()]); + final PsiElement[] occurrences = collectVariableUsages(variable, scope); return new GrIntroduceContextImpl(project, editor, null, variable, stringPart, occurrences, scope); } else if (expression != null ) { @@ -463,6 +452,21 @@ public abstract class GrIntroduceHandlerBase list = Collections.synchronizedList(new ArrayList()); + ReferencesSearch.search(variable, new LocalSearchScope(scope)).forEach(new Processor() { + @Override + public boolean process(PsiReference psiReference) { + final PsiElement element = psiReference.getElement(); + if (element != null) { + list.add(element); + } + return true; + } + }); + return list.toArray(new PsiElement[list.size()]); + } + private boolean invokeImpl(final Project project, final GrIntroduceContext context, final Editor editor) { try { if (!CommonRefactoringUtil.checkReadOnlyStatus(project, context.getOccurrences())) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/StringPartInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/StringPartInfo.java index 36ff8b45280d..d37f5bad5a5a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/StringPartInfo.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/StringPartInfo.java @@ -282,6 +282,7 @@ public class StringPartInfo { return myInjections; } + @NotNull public GrLiteral createLiteralFromSelected() { return (GrLiteral)GroovyPsiElementFactory.getInstance(myLiteral.getProject()).createExpressionFromText(prepareSelected()); } 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 f100448e4255..849cac3ae08a 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 @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrExpressionWrapper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrExpressionWrapper.java index 4bb4ee85ffd3..99ea5a7f84ac 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrExpressionWrapper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrExpressionWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -34,7 +34,7 @@ public class GrExpressionWrapper implements IntroduceParameterData.ExpressionWra private final RangeMarker myMarker; private final PsiFile myFile; - public GrExpressionWrapper(GrExpression expression) { + public GrExpressionWrapper(@NotNull GrExpression expression) { assert expression.isValid(); myExpression = expression; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrInplaceParameterIntroducer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrInplaceParameterIntroducer.java index 26c00354833e..b9595d04a59d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrInplaceParameterIntroducer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrInplaceParameterIntroducer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -18,132 +18,85 @@ package org.jetbrains.plugins.groovy.refactoring.introduce.parameter; import com.intellij.codeInsight.template.TextResult; import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.EditorFactory; -import com.intellij.openapi.editor.EditorSettings; -import com.intellij.openapi.editor.RangeMarker; -import com.intellij.openapi.editor.colors.EditorColors; import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.editor.event.DocumentEvent; -import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.impl.DocumentMarkupModel; import com.intellij.openapi.editor.markup.EffectType; import com.intellij.openapi.editor.markup.HighlighterTargetArea; import com.intellij.openapi.editor.markup.MarkupModel; import com.intellij.openapi.editor.markup.TextAttributes; -import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiParameter; -import com.intellij.psi.PsiVariable; +import com.intellij.psi.PsiType; import com.intellij.refactoring.IntroduceParameterRefactoring; +import com.intellij.refactoring.introduce.inplace.OccurrencesChooser; import com.intellij.refactoring.rename.inplace.InplaceRefactoring; -import com.intellij.ui.DottedBorder; import com.intellij.ui.JBColor; import com.intellij.ui.components.JBCheckBox; +import com.intellij.usageView.UsageInfo; import com.intellij.util.ArrayUtil; import gnu.trove.TIntArrayList; -import gnu.trove.TObjectIntHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrParametersOwner; 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.params.GrParameter; -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.GrIntroduceHandlerBase; import javax.swing.*; import javax.swing.border.EmptyBorder; -import javax.swing.border.LineBorder; import java.awt.*; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; +import static org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GroovyIntroduceParameterUtil.findParametersToRemove; + /** * Created by Max Medvedev on 9/1/13 */ -public class GrInplaceParameterIntroducer extends GrInplaceIntroducer { - private final JPanel myPanel; - private EditorEx myPreview; +public class GrInplaceParameterIntroducer extends GrAbstractInplaceIntroducer { + private final IntroduceParameterInfo myInfo; + private final TIntArrayList myParametersToRemove; - private JComponent myPreviewComponent; private JBCheckBox myDelegateCB; - private GrIntroduceParameterSettings mySettings; - private final GrExpressionWrapper myExpr; + private LinkedHashSet mySuggestedNames; - public GrInplaceParameterIntroducer(@NotNull GrVariable elementToRename, - @NotNull Editor editor, - @NotNull Project project, - @NotNull String title, - @NotNull List occurrences, - @Nullable PsiElement elementToIntroduce, - GrIntroduceParameterSettings settings, - GrExpressionWrapper expr) { - super(elementToRename, editor, project, title, occurrences, elementToIntroduce); + public GrInplaceParameterIntroducer(IntroduceParameterInfo info, GrIntroduceContext context, OccurrencesChooser.ReplaceChoice choice) { + super(GrIntroduceParameterHandler.REFACTORING_NAME, choice, context); + myInfo = info; - mySettings = settings; - - initPreview(project); - - myDelegateCB = new JBCheckBox("Delegate via overloading method"); - myDelegateCB.setMnemonic('l'); - myDelegateCB.setFocusable(false); - - myPanel = new JPanel(new BorderLayout()); - myPanel.add(myPreviewComponent, BorderLayout.CENTER); - myPanel.add(myDelegateCB, BorderLayout.SOUTH); - - myExpr = expr; + GrVariable localVar = GrIntroduceHandlerBase.resolveLocalVar(context); + mySuggestedNames = GroovyIntroduceParameterUtil.suggestNames(localVar, context.getExpression(), context.getStringPart(), info.getToReplaceIn(), context.getProject()); + myParametersToRemove = new TIntArrayList(findParametersToRemove(info).getValues()); } - protected final void setPreviewText(final String text) { - if (myPreview == null) return; //already disposed - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - myPreview.getDocument().replaceString(0, myPreview.getDocument().getTextLength(), text); - } - }); + @Override + protected String getActionName() { + return GrIntroduceParameterHandler.REFACTORING_NAME; } + @Override + protected String[] suggestNames(boolean replaceAll, @Nullable GrVariable variable) { + return ArrayUtil.toStringArray(mySuggestedNames); + } - private void initPreview(Project project) { - myPreview = (EditorEx)EditorFactory.getInstance() - .createEditor(EditorFactory.getInstance().createDocument(""), project, GroovyFileType.GROOVY_FILE_TYPE, true); - myPreview.setOneLineMode(true); - final EditorSettings settings = myPreview.getSettings(); - settings.setAdditionalLinesCount(0); - settings.setAdditionalColumnsCount(1); - settings.setRightMarginShown(false); - settings.setFoldingOutlineShown(false); - settings.setLineNumbersShown(false); - settings.setLineMarkerAreaShown(false); - settings.setIndentGuidesShown(false); - settings.setVirtualSpace(false); - myPreview.setHorizontalScrollbarVisible(false); - myPreview.setVerticalScrollbarVisible(false); - myPreview.setCaretEnabled(false); - settings.setLineCursorWidth(1); + @Override + protected JComponent getComponent() { - final Color bg = myPreview.getColorsScheme().getColor(EditorColors.CARET_ROW_COLOR); - myPreview.setBackgroundColor(bg); - myPreview.setBorder(BorderFactory.createCompoundBorder(new DottedBorder(JBColor.GRAY), new LineBorder(bg, 2))); - - myPreviewComponent = new JPanel(new BorderLayout()); - myPreviewComponent.add(myPreview.getComponent(), BorderLayout.CENTER); - myPreviewComponent.setBorder(new EmptyBorder(2, 2, 6, 2)); + JPanel previewPanel = new JPanel(new BorderLayout()); + previewPanel.add(getPreviewEditor().getComponent(), BorderLayout.CENTER); + previewPanel.setBorder(new EmptyBorder(2, 2, 6, 2)); DocumentAdapter documentAdapter = new DocumentAdapter() { @Override public void documentChanged(DocumentEvent e) { - if (myPreview == null) return; final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor); if (templateState != null) { final TextResult value = templateState.getVariableValue(InplaceRefactoring.PRIMARY_VARIABLE_NAME); @@ -155,59 +108,29 @@ public class GrInplaceParameterIntroducer extends GrInplaceIntroducer { }; myEditor.getDocument().addDocumentListener(documentAdapter); - updateTitle(getVariable(), getVariable().getName()); + myDelegateCB = new JBCheckBox("Delegate via overloading method"); + myDelegateCB.setMnemonic('l'); + myDelegateCB.setFocusable(false); + + JPanel panel = new JPanel(new BorderLayout()); + panel.add(previewPanel, BorderLayout.CENTER); + panel.add(myDelegateCB, BorderLayout.SOUTH); + return panel; } @Override - public LinkedHashSet suggestNames(GrIntroduceContext context) { - return GroovyIntroduceParameterUtil.suggestNames(null, myExpr.getExpression(), null, (GrParametersOwner)context.getScope(), context.getProject()); + protected void saveSettings(@NotNull GrVariable variable) { + } - static LinkedHashSet suggestNames(GrIntroduceContext context, GrParametersOwner scope) { - return GroovyIntroduceParameterUtil.suggestNames(context.getVar(), context.getExpression(), context.getStringPart(), scope, context.getProject()); - } - - @Override - protected void moveOffsetAfter(boolean success) { - if (success) { - final GrVariable parameter = getVariable(); - GrIntroduceParameterSettings settings = generateSettings((GrParameter)parameter, mySettings, myDelegateCB.isSelected()); - assert parameter != null; - parameter.delete(); - GrIntroduceParameterProcessor processor = new GrIntroduceParameterProcessor(settings, myExpr); - processor.run(); - } - - - super.moveOffsetAfter(success); - } - - public GrIntroduceParameterSettings generateSettings(GrParameter parameter, IntroduceParameterInfo info, boolean delegate) { - - TObjectIntHashMap toRemove = GroovyIntroduceParameterUtil.findParametersToRemove(info); - TIntArrayList removeList = new TIntArrayList(delegate ? ArrayUtil.EMPTY_INT_ARRAY: toRemove.getValues()); - - GrExpression _expr = myExpr.getExpression(); - GrVariable _var = GroovyIntroduceParameterUtil.findVar(info); - return new GrIntroduceExpressionSettingsImpl(info, parameter.getName(), false, removeList, myDelegateCB.isSelected(), - IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, _expr, _var, - parameter.getType(), false, false); - } - - @Override - protected JComponent getComponent() { - updateTitle(getVariable()); - return myPanel; - } - - - protected void updateTitle(@Nullable PsiVariable variable) { + protected void updateTitle(@Nullable GrVariable variable) { if (variable == null) return; updateTitle(variable, variable.getName()); } - protected void updateTitle(@Nullable final PsiVariable variable, final String value) { - final PsiElement declarationScope = variable != null ? ((PsiParameter)variable).getDeclarationScope() : null; + protected void updateTitle(@Nullable GrVariable variable, String value) { + if (getPreviewEditor() == null || variable == null) return; + final PsiElement declarationScope = ((PsiParameter)variable).getDeclarationScope(); if (declarationScope instanceof PsiMethod) { final PsiMethod psiMethod = (PsiMethod)declarationScope; final StringBuilder buf = new StringBuilder(); @@ -233,15 +156,17 @@ public class GrInplaceParameterIntroducer extends GrInplaceIntroducer { if (variable == parameter) { addedRange = new TextRange(startOffset, endOffset); } - else if (mySettings.parametersToRemove().contains(i)) { + else if (myParametersToRemove.contains(i)) { ranges2Remove.add(new TextRange(startOffset, endOffset)); } i++; } + assert addedRange != null; + buf.append(")"); setPreviewText(buf.toString()); - final MarkupModel markupModel = DocumentMarkupModel.forDocument(myPreview.getDocument(), myProject, true); + final MarkupModel markupModel = DocumentMarkupModel.forDocument(getPreviewEditor().getDocument(), myProject, true); markupModel.removeAllHighlighters(); for (TextRange textRange : ranges2Remove) { markupModel.addRangeHighlighter(textRange.getStartOffset(), textRange.getEndOffset(), 0, getTestAttributesForRemoval(), HighlighterTargetArea.EXACT_RANGE); @@ -261,7 +186,61 @@ public class GrInplaceParameterIntroducer extends GrInplaceIntroducer { private static TextAttributes getTestAttributesForRemoval() { final TextAttributes textAttributes = new TextAttributes(); textAttributes.setEffectType(EffectType.STRIKEOUT); - textAttributes.setEffectColor(Color.BLACK); + textAttributes.setEffectColor(JBColor.BLACK); return textAttributes; } + + @Override + protected GrVariable runRefactoring(GrIntroduceContext context, GrIntroduceParameterSettings settings, boolean processUsages) { + GrExpressionWrapper wrapper = createExpressionWrapper(context); + if (processUsages) { + GrIntroduceExpressionSettingsImpl patchedSettings = + new GrIntroduceExpressionSettingsImpl(settings, settings.getName(), settings.declareFinal(), settings.parametersToRemove(), + settings.generateDelegate(), settings.replaceFieldsWithGetters(), context.getExpression(), + context.getVar(), settings.getSelectedType(), context.getVar() != null || settings.replaceAllOccurrences(), + context.getVar() != null, settings.isForceReturn()); + GrIntroduceParameterProcessor processor = new GrIntroduceParameterProcessor(patchedSettings, wrapper); + processor.run(); + } + else { + GrIntroduceParameterProcessor processor = new GrIntroduceParameterProcessor(settings, wrapper); + processor.performRefactoring(UsageInfo.EMPTY_ARRAY); + } + GrParametersOwner owner = settings.getToReplaceIn(); + return ArrayUtil.getLastElement(owner.getParameters()); + } + + @NotNull + private static GrExpressionWrapper createExpressionWrapper(@NotNull GrIntroduceContext context) { + GrExpression expression = context.getExpression(); + GrVariable var = context.getVar(); + assert expression != null || var != null ; + + GrExpression initializer = expression != null ? expression : var.getInitializerGroovy(); + return new GrExpressionWrapper(initializer); + } + + @Nullable + @Override + protected GrIntroduceParameterSettings getInitialSettingsForInplace(@NotNull GrIntroduceContext context, + @NotNull OccurrencesChooser.ReplaceChoice choice, + String[] names) { + GrExpression expression = context.getExpression(); + GrVariable var = context.getVar(); + PsiType type = var != null ? var.getDeclaredType() : + expression != null ? expression.getType() : + null; + + return new GrIntroduceExpressionSettingsImpl(myInfo, names[0], false, myParametersToRemove, false, + IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, expression, + var, type, false, false, false); + + } + + @Override + protected GrIntroduceParameterSettings getSettings() { + return new GrIntroduceExpressionSettingsImpl(myInfo, getInputName(), false, myParametersToRemove, myDelegateCB.isSelected(), + IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, null, + null, getSelectedType(), isReplaceAllOccurrences(), false, false); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java index 70c5ac6d7f9e..84389a632249 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceClosureParameterProcessor.java @@ -92,7 +92,7 @@ public class GrIntroduceClosureParameterProcessor extends BaseRefactoringProcess private GrExpressionWrapper myParameterInitializer; private GroovyPsiElementFactory myFactory = GroovyPsiElementFactory.getInstance(myProject); - public GrIntroduceClosureParameterProcessor(GrIntroduceParameterSettings settings) { + public GrIntroduceClosureParameterProcessor(@NotNull GrIntroduceParameterSettings settings) { super(settings.getProject(), null); mySettings = settings; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceExpressionSettingsImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceExpressionSettingsImpl.java index e0c42410caf7..3113473a7d95 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceExpressionSettingsImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceExpressionSettingsImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -31,6 +31,7 @@ public class GrIntroduceExpressionSettingsImpl extends ExtractClosureHelperImpl private final GrExpression myExpr; private final GrVariable myVar; private final PsiType mySelectedType; + private final boolean myRemoveLocalVar; public GrIntroduceExpressionSettingsImpl(IntroduceParameterInfo info, String name, @@ -44,11 +45,13 @@ public class GrIntroduceExpressionSettingsImpl extends ExtractClosureHelperImpl GrVariable var, PsiType selectedType, boolean replaceAllOccurrences, + boolean removeLocalVar, boolean forceReturn) { super(info, name, declareFinal, toRemove, generateDelegate, replaceFieldsWithGetters, forceReturn, replaceAllOccurrences, false); myExpr = expr; myVar = var; mySelectedType = selectedType; + myRemoveLocalVar = removeLocalVar; } @Override @@ -67,4 +70,8 @@ public class GrIntroduceExpressionSettingsImpl extends ExtractClosureHelperImpl } + @Override + public boolean removeLocalVariable() { + return myRemoveLocalVar; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterDialog.java index 2bb3636243eb..bd63f95de532 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterDialog.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -75,6 +75,7 @@ import java.util.LinkedHashSet; import java.util.List; import static com.intellij.refactoring.IntroduceParameterRefactoring.*; +import static org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GroovyIntroduceParameterUtil.*; public class GrIntroduceParameterDialog extends DialogWrapper { private GrTypeComboBox myTypeComboBox; @@ -100,9 +101,11 @@ public class GrIntroduceParameterDialog extends DialogWrapper { super(info.getProject(), true); myInfo = info; myProject = info.getProject(); - myCanIntroduceSimpleParameter = GroovyIntroduceParameterUtil.findExpr(myInfo) != null || GroovyIntroduceParameterUtil.findVar(myInfo) != null || findStringPart() != null; + myCanIntroduceSimpleParameter = findExpr(myInfo) != null || + findVar(myInfo) != null || + findStringPart() != null; - TObjectIntHashMap parametersToRemove = GroovyIntroduceParameterUtil.findParametersToRemove(info); + TObjectIntHashMap parametersToRemove = findParametersToRemove(info); toRemoveCBs = new TObjectIntHashMap(parametersToRemove.size()); for (Object p : parametersToRemove.keys()) { JCheckBox cb = new JCheckBox(GroovyRefactoringBundle.message("remove.parameter.0.no.longer.used", ((GrParameter)p).getName())); @@ -274,7 +277,7 @@ public class GrIntroduceParameterDialog extends DialogWrapper { c.nextLine().next().weightx(0).fillCellNone(); namePanel.add(typeLabel, c); - myTypeComboBox = createTypeComboBox(GroovyIntroduceParameterUtil.findVar(myInfo), GroovyIntroduceParameterUtil.findExpr(myInfo), findStringPart()); + myTypeComboBox = createTypeComboBox(findVar(myInfo), findExpr(myInfo), findStringPart()); c.next().weightx(1).fillCellHorizontally(); namePanel.add(myTypeComboBox, c); typeLabel.setLabelFor(myTypeComboBox); @@ -283,7 +286,7 @@ public class GrIntroduceParameterDialog extends DialogWrapper { c.nextLine().next().weightx(0).fillCellNone(); namePanel.add(nameLabel, c); - myNameSuggestionsField = createNameField(GroovyIntroduceParameterUtil.findVar(myInfo)); + myNameSuggestionsField = createNameField(findVar(myInfo)); c.next().weightx(1).fillCellHorizontally(); namePanel.add(myNameSuggestionsField, c); nameLabel.setLabelFor(myNameSuggestionsField); @@ -358,7 +361,7 @@ public class GrIntroduceParameterDialog extends DialogWrapper { } private void initReplaceFieldsWithGetters(JavaRefactoringSettings settings) { - final PsiField[] usedFields = GroovyIntroduceParameterUtil.findUsedFieldsWithGetters(myInfo.getStatements(), getContainingClass()); + final PsiField[] usedFields = findUsedFieldsWithGetters(myInfo.getStatements(), getContainingClass()); myGetterPanel.setVisible(usedFields.length > 0); switch (settings.INTRODUCE_PARAMETER_REPLACE_FIELDS_WITH_GETTERS) { case REPLACE_FIELDS_WITH_GETTERS_ALL: @@ -452,8 +455,8 @@ public class GrIntroduceParameterDialog extends DialogWrapper { final GrParametersOwner toReplaceIn = myInfo.getToReplaceIn(); - final GrExpression expr = GroovyIntroduceParameterUtil.findExpr(myInfo); - final GrVariable var = GroovyIntroduceParameterUtil.findVar(myInfo); + final GrExpression expr = findExpr(myInfo); + final GrVariable var = findVar(myInfo); final StringPartInfo stringPart = findStringPart(); if (myTypeComboBox.isClosureSelected() || expr == null && var == null && stringPart == null) { @@ -484,7 +487,7 @@ public class GrIntroduceParameterDialog extends DialogWrapper { expr, var, myTypeComboBox.getSelectedType(), - false, myForceReturnCheckBox.isSelected()); + var != null, true, myForceReturnCheckBox.isSelected()); if (toReplaceIn instanceof GrMethod) { invokeRefactoring(new GrIntroduceParameterProcessor(settings)); } @@ -522,8 +525,8 @@ public class GrIntroduceParameterDialog extends DialogWrapper { @NotNull public LinkedHashSet suggestNames() { - GrVariable var = GroovyIntroduceParameterUtil.findVar(myInfo); - GrExpression expr = GroovyIntroduceParameterUtil.findExpr(myInfo); + GrVariable var = findVar(myInfo); + GrExpression expr = findExpr(myInfo); StringPartInfo stringPart = findStringPart(); return GroovyIntroduceParameterUtil.suggestNames(var, expr, stringPart, myInfo.getToReplaceIn(), myProject); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterHandler.java index 6e2ba790997c..9f1a9848476f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterHandler.java @@ -18,19 +18,16 @@ package org.jetbrains.plugins.groovy.refactoring.introduce.parameter; import com.intellij.ide.util.SuperMethodWarningUtil; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.command.CommandProcessor; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.editor.SelectionModel; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopup; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Pass; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiMethod; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.refactoring.IntroduceParameterRefactoring; import com.intellij.refactoring.IntroduceTargetChooser; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.RefactoringBundle; @@ -38,34 +35,31 @@ import com.intellij.refactoring.introduce.inplace.OccurrencesChooser; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.util.Function; import com.intellij.util.PairFunction; -import com.intellij.util.containers.ContainerUtil; -import gnu.trove.TIntArrayList; -import gnu.trove.TObjectIntHashMap; 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.api.statements.GrParametersOwner; 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.GrExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.refactoring.GrRefactoringError; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; import org.jetbrains.plugins.groovy.refactoring.extract.GroovyExtractChooser; import org.jetbrains.plugins.groovy.refactoring.extract.InitialInfo; -import org.jetbrains.plugins.groovy.refactoring.introduce.*; -import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.java2groovy.GroovyIntroduceParameterMethodUsagesProcessor; +import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext; +import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceHandlerBase; +import org.jetbrains.plugins.groovy.refactoring.introduce.IntroduceOccurrencesChooser; +import org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo; import org.jetbrains.plugins.groovy.refactoring.introduce.variable.GrIntroduceVariableHandler; import org.jetbrains.plugins.groovy.refactoring.ui.MethodOrClosureScopeChooser; import java.util.ArrayList; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import static org.jetbrains.plugins.groovy.refactoring.HelpID.GROOVY_INTRODUCE_PARAMETER; -import static org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceHandlerBase.createRange; +import static org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GroovyIntroduceParameterUtil.findExpr; +import static org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GroovyIntroduceParameterUtil.findVar; /** * @author Maxim.Medvedev @@ -74,7 +68,7 @@ public class GrIntroduceParameterHandler implements RefactoringActionHandler, Me static final String REFACTORING_NAME = RefactoringBundle.message("introduce.parameter.title"); private JBPopup myEnclosingMethodsPopup; - public void invoke(final @NotNull Project project, final Editor editor, final PsiFile file, final @Nullable DataContext dataContext) { + public void invoke(final @NotNull Project project, @NotNull final Editor editor, @NotNull final PsiFile file, final @Nullable DataContext dataContext) { final SelectionModel selectionModel = editor.getSelectionModel(); if (!selectionModel.hasSelection()) { final int offset = editor.getCaretModel().getOffset(); @@ -105,7 +99,7 @@ public class GrIntroduceParameterHandler implements RefactoringActionHandler, Me invoke(project, editor, file, selectionModel.getSelectionStart(), selectionModel.getSelectionEnd()); } - private void invoke(final Project project, final Editor editor, PsiFile file, int startOffset, int endOffset) { + private void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file, int startOffset, int endOffset) { try { final InitialInfo initialInfo = GroovyExtractChooser.invoke(project, editor, file, startOffset, endOffset, false); chooseScopeAndRun(initialInfo, editor); @@ -146,7 +140,8 @@ public class GrIntroduceParameterHandler implements RefactoringActionHandler, Me } } - private List findScopes(InitialInfo initialInfo) { + @NotNull + private static List findScopes(@NotNull InitialInfo initialInfo) { PsiElement place = initialInfo.getContext(); final List scopes = new ArrayList(); while (true) { @@ -165,14 +160,14 @@ public class GrIntroduceParameterHandler implements RefactoringActionHandler, Me //method to hack in tests - protected void showDialogOrStartInplace(final IntroduceParameterInfo info, final Editor editor) { + protected void showDialogOrStartInplace(@NotNull final IntroduceParameterInfo info, @NotNull final Editor editor) { if (isInplace(info, editor)) { final GrIntroduceContext context = createContext(info, editor); Map> occurrencesMap = GrIntroduceHandlerBase.fillChoice(context); new IntroduceOccurrencesChooser(editor).showChooser(new Pass() { @Override public void pass(OccurrencesChooser.ReplaceChoice choice) { - startInplace(info, context, choice == OccurrencesChooser.ReplaceChoice.ALL); + startInplace(info, context, choice); } }, occurrencesMap); } @@ -185,112 +180,27 @@ public class GrIntroduceParameterHandler implements RefactoringActionHandler, Me new GrIntroduceParameterDialog(info).show(); } - private void startInplace(final IntroduceParameterInfo info, final GrIntroduceContext context, boolean replaceAll) { - final GrIntroduceParameterSettings settings = getSettingsForInplace(info, context, replaceAll); - if (settings == null) return; - - CommandProcessor.getInstance().executeCommand(info.getProject(), new Runnable() { - public void run() { - Document document = context.getEditor().getDocument(); - - List occurrences = ContainerUtil.newArrayList(); - if (settings.replaceAllOccurrences()) { - for (PsiElement element : context.getOccurrences()) { - occurrences.add(createRange(document, element)); - } - } - else if (context.getExpression() != null) { - occurrences.add(createRange(document, context.getExpression())); - } - - GrExpressionWrapper expr = new GrExpressionWrapper(GroovyIntroduceParameterUtil.findExpr(settings)); - - SmartPsiElementPointer pointer = - ApplicationManager.getApplication().runWriteAction(new Computable>() { - @Override - public SmartPsiElementPointer compute() { - Project project = context.getProject(); - GrParametersOwner toReplaceIn = info.getToReplaceIn(); - String name = GrInplaceParameterIntroducer.suggestNames(context, toReplaceIn).iterator().next(); - PsiType type = getType(context.getExpression(), context.getVar(), context.getStringPart()); - GrParameter parameter = GroovyIntroduceParameterMethodUsagesProcessor.addParameter( - toReplaceIn, null, - type != null ? type : PsiType.getJavaLangObject(PsiManager.getInstance(project), toReplaceIn.getResolveScope()), name, - false, project); - GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project); - - if (settings.replaceAllOccurrences()) { - for (PsiElement element : context.getOccurrences()) { - element.replace(factory.createReferenceExpressionFromText(name)); - } - } - else { - context.getExpression().replace(factory.createReferenceExpressionFromText(name)); - } - return SmartPointerManager.getInstance(project).createSmartPsiElementPointer(parameter); - } - }); - GrVariable parameter = pointer != null ? pointer.getElement() : null; - - if (parameter != null) { - GrInplaceIntroducer introducer = getIntroducer(parameter, context, settings, occurrences, expr); - PsiDocumentManager.getInstance(info.getProject()).doPostponedOperationsAndUnblockDocument(context.getEditor().getDocument()); - introducer.performInplaceRefactoring(introducer.suggestNames(context)); - } - } - }, REFACTORING_NAME, REFACTORING_NAME); - + private static void startInplace(@NotNull final IntroduceParameterInfo info, + @NotNull final GrIntroduceContext context, + OccurrencesChooser.ReplaceChoice replaceChoice) { + new GrInplaceParameterIntroducer(info, context, replaceChoice).startInplaceIntroduceTemplate(); } - private static GrInplaceIntroducer getIntroducer(GrVariable parameter, - GrIntroduceContext context, - GrIntroduceParameterSettings settings, - List occurrences, - GrExpressionWrapper expr) { - return new GrInplaceParameterIntroducer(parameter, context.getEditor(), context.getProject(), REFACTORING_NAME, occurrences, context.getPlace(), settings, expr); + private static boolean isInplace(@NotNull IntroduceParameterInfo info, + @NotNull Editor editor) { + return findExpr(info) != null && GrIntroduceHandlerBase.isInplace(editor, info.getContext()); } - private static GrIntroduceParameterSettings getSettingsForInplace(@NotNull IntroduceParameterInfo info, - @NotNull GrIntroduceContext context, - boolean replaceAll) { - GrExpression expr = context.getExpression(); - GrVariable var = context.getVar(); - - TObjectIntHashMap toRemove = GroovyIntroduceParameterUtil.findParametersToRemove(info); - LinkedHashSet names = - GroovyIntroduceParameterUtil.suggestNames(var, expr, info.getStringPartInfo(), info.getToReplaceIn(), info.getProject()); - return new GrIntroduceExpressionSettingsImpl(info, names.iterator().next(), false, new TIntArrayList(toRemove.getValues()), false, - IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, expr, var, - getType(expr, var, info.getStringPartInfo()), replaceAll, false); - } - - @Nullable - private static PsiType getType(GrExpression expr, GrVariable var, StringPartInfo info) { - if (expr != null) { - return expr.getType(); - } - else if (var != null) { - return var.getDeclaredType(); - } - else if (info != null) { - return info.getLiteral().getType(); - } - return null; - } - - private static boolean isInplace(IntroduceParameterInfo info, Editor editor) { - return GroovyIntroduceParameterUtil.findExpr(info) != null && GrIntroduceHandlerBase.isInplace(editor, info.getContext()); - } - - @Override public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) { // Does nothing } - private static GrIntroduceContext createContext(IntroduceParameterInfo info, Editor editor) { - GrExpression expr = GroovyIntroduceParameterUtil.findExpr(info); - GrVariable var = GroovyIntroduceParameterUtil.findVar(info); - return new GrIntroduceVariableHandler().getContext(info.getProject(), editor, expr, var, info.getStringPartInfo(), info.getToReplaceIn()); + private static GrIntroduceContext createContext(@NotNull IntroduceParameterInfo info, + @NotNull Editor editor) { + GrExpression expr = findExpr(info); + GrVariable var = findVar(info); + StringPartInfo stringPart = info.getStringPartInfo(); + return new GrIntroduceVariableHandler().getContext(info.getProject(), editor, expr, var, stringPart, info.getToReplaceIn()); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterProcessor.java index a27b2ceaf0b8..9a5ccb002647 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterProcessor.java @@ -46,6 +46,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; +import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceHandlerBase; import org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo; import org.jetbrains.plugins.groovy.refactoring.util.AnySupers; @@ -77,9 +78,10 @@ public class GrIntroduceParameterProcessor extends BaseRefactoringProcessor impl LOG.assertTrue(settings.getToSearchFor() instanceof PsiMethod); final StringPartInfo stringPartInfo = settings.getStringPartInfo(); - final GrExpression expression = stringPartInfo != null - ? stringPartInfo.createLiteralFromSelected() - : settings.getExpression(); + GrVariable var = settings.getVar(); + final GrExpression expression = stringPartInfo != null ? stringPartInfo.createLiteralFromSelected() : + var != null ? var.getInitializerGroovy() + : settings.getExpression(); return new GrExpressionWrapper(expression); } @@ -176,9 +178,16 @@ public class GrIntroduceParameterProcessor extends BaseRefactoringProcessor impl } if (mySettings.replaceAllOccurrences()) { - PsiElement[] exprs = GroovyIntroduceParameterUtil.getOccurrences(mySettings); - for (PsiElement expr : exprs) { - result.add(new InternalUsageInfo(expr)); + if (mySettings.getVar() != null) { + for (PsiElement element : GrIntroduceHandlerBase.collectVariableUsages(mySettings.getVar(), mySettings.getToReplaceIn())) { + result.add(new InternalUsageInfo(element)); + } + } + else { + PsiElement[] exprs = GroovyIntroduceParameterUtil.getOccurrences(mySettings); + for (PsiElement expr : exprs) { + result.add(new InternalUsageInfo(expr)); + } } } else { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GroovyIntroduceParameterUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GroovyIntroduceParameterUtil.java index 5391a68df73b..ef1e8f73ea58 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GroovyIntroduceParameterUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GroovyIntroduceParameterUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -379,6 +379,9 @@ public class GroovyIntroduceParameterUtil { @Nullable static GrVariable findVar(IntroduceParameterInfo info) { + GrVariable variable = info.getVar(); + if (variable != null) return variable; + final GrStatement[] statements = info.getStatements(); if (statements.length != 1) return null; return GrIntroduceHandlerBase.findVariable(statements[0]); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy index 3956cf8da7be..550c5a1e3144 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy @@ -25,7 +25,6 @@ import com.intellij.psi.impl.source.PostprocessReformattingAspect import com.intellij.refactoring.IntroduceParameterRefactoring import gnu.trove.TIntArrayList import gnu.trove.TObjectIntHashMap -import junit.framework.Assert import org.jetbrains.annotations.Nullable import org.jetbrains.plugins.groovy.LightGroovyTestCase import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement @@ -37,6 +36,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceHandlerBase import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.* import org.jetbrains.plugins.groovy.util.TestUtils +import org.junit.Assert /** * @author Maxim.Medvedev @@ -123,37 +123,32 @@ public class GrIntroduceParameterTest extends LightGroovyTestCase { final Project project, final Editor editor, final PsiFile file) { - CommandProcessor.getInstance().executeCommand(project, new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - try { - final GrIntroduceParameterHandler hackedHandler = new GrIntroduceParameterHandler() { - @Override - protected void showDialog(IntroduceParameterInfo info) { - final GrIntroduceParameterSettings hackedSettings = GrIntroduceParameterTest.getSettings(info, removeUnusedParameters, replaceFieldsWithGetters, declareFinal, generateDelegate); - if (info.getToReplaceIn() instanceof GrMethod) { - new GrIntroduceParameterProcessor(hackedSettings).run(); - } - else { - new GrIntroduceClosureParameterProcessor(hackedSettings).run(); - } - } - }; - hackedHandler.invoke(project, editor, file, null); - if (conflicts != null) fail("Conflicts were expected"); - } - catch (Exception e) { - if (conflicts == null) { - e.printStackTrace(); - fail("Conflicts were not expected"); + CommandProcessor.instance.executeCommand(project, { + ApplicationManager.application.runWriteAction { + try { + final GrIntroduceParameterHandler hackedHandler = new GrIntroduceParameterHandler() { + @Override + protected void showDialog(IntroduceParameterInfo info) { + final GrIntroduceParameterSettings hackedSettings = + getSettings(info, removeUnusedParameters, replaceFieldsWithGetters, declareFinal, generateDelegate); + if (info.getToReplaceIn() instanceof GrMethod) { + new GrIntroduceParameterProcessor(hackedSettings).run(); + } + else { + new GrIntroduceClosureParameterProcessor(hackedSettings).run(); } - Assert.assertEquals(conflicts, e.getMessage()); } + }; + hackedHandler.invoke(project, editor, file, null); + if (conflicts != null) fail("Conflicts were expected"); + } + catch (Exception e) { + if (conflicts == null) { + e.printStackTrace(); + fail("Conflicts were not expected"); } - }); + Assert.assertEquals(conflicts, e.getMessage()); + } } }, "introduce Parameter", null); } @@ -174,11 +169,10 @@ public class GrIntroduceParameterTest extends LightGroovyTestCase { final GrStatement[] statements = context.getStatements() GrExpression expr = statements.length == 1 ? GrIntroduceHandlerBase.findExpression(statements[0]) : null; - GrVariable var = statements.length == 1 ? GrIntroduceHandlerBase.findVariable(context.getStatements()[0]) : null; - final PsiType type = TypesUtil. - unboxPrimitiveTypeWrapper(var != null ? var.getType() : expr != null ? expr.getType() : context.stringPartInfo.literal.type); + GrVariable var = context.var + final PsiType type = TypesUtil.unboxPrimitiveTypeWrapper(var != null ? var.getType() : expr != null ? expr.getType() : context.stringPartInfo.literal.type); return new GrIntroduceExpressionSettingsImpl(context, "anObject", declareFinal, toRemove, generateDelegate, replaceFieldsWithGetters, - expr, var, type, false, true); + expr, var, type, var !=null, var != null, true); } @@ -375,6 +369,25 @@ def foo(anObject) { } foo(print(a)) +''') + } + + void testIntroduceFromLocalVar() { + doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null, false, '''\ +def foo() { + def var = 5 + + print var + var +} + +foo() +''', '''\ +def foo(anObject) { + + print anObject + anObject +} + +foo(5) ''') } }