diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java index 325c25b14d3a..aa1a253d5b96 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterPopup.java @@ -38,7 +38,7 @@ import java.util.List; * User: anna * Date: 2/25/11 */ -class InplaceIntroduceParameterPopup extends AbstractJavaInplaceIntroducer { +public class InplaceIntroduceParameterPopup extends AbstractJavaInplaceIntroducer { private static final Logger LOG = Logger.getInstance("#" + InplaceIntroduceParameterPopup.class.getName()); private final Project myProject; @@ -170,7 +170,7 @@ class InplaceIntroduceParameterPopup extends AbstractJavaInplaceIntroducer { parametersToRemove); final Runnable runnable = new Runnable() { public void run() { - ApplicationManager.getApplication().invokeLater(new Runnable() { + final Runnable performRefactoring = new Runnable() { public void run() { final boolean[] conflictsFound = new boolean[]{true}; processor.setPrepareSuccessfulSwingThreadCallback(new Runnable() { @@ -184,7 +184,12 @@ class InplaceIntroduceParameterPopup extends AbstractJavaInplaceIntroducer { InplaceIntroduceParameterPopup.super.moveOffsetAfter(!conflictsFound[0]); InplaceIntroduceParameterPopup.super.saveSettings(getParameter()); } - }); + }; + if (ApplicationManager.getApplication().isUnitTestMode()) { + performRefactoring.run(); + } else { + ApplicationManager.getApplication().invokeLater(performRefactoring); + } } }; CommandProcessor.getInstance().executeCommand(myProject, runnable, getCommandName(), null); @@ -205,4 +210,8 @@ class InplaceIntroduceParameterPopup extends AbstractJavaInplaceIntroducer { } }); } + + public void setReplaceAllOccurrences(boolean replaceAll) { + myPanel.setReplaceAllOccurrences(replaceAll); + } } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterUI.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterUI.java index 27bf5707b015..1b9d35e94acd 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterUI.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/InplaceIntroduceParameterUI.java @@ -199,4 +199,11 @@ public abstract class InplaceIntroduceParameterUI extends IntroduceParameterSett final Boolean createFinals = JavaRefactoringSettings.getInstance().INTRODUCE_PARAMETER_CREATE_FINALS; return createFinals == null ? CodeStyleSettingsManager.getSettings(myProject).GENERATE_FINAL_PARAMETERS : createFinals.booleanValue(); } + + + public void setReplaceAllOccurrences(boolean replaceAll) { + if (myCbReplaceAllOccurences != null) { + myCbReplaceAllOccurences.setSelected(replaceAll); + } + } } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java index 860ece8c1a5a..905695303103 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java @@ -35,7 +35,10 @@ import com.intellij.openapi.editor.colors.EditorColors; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.markup.*; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.popup.*; +import com.intellij.openapi.ui.popup.JBPopup; +import com.intellij.openapi.ui.popup.JBPopupAdapter; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.LightweightWindowEvent; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Pass; import com.intellij.openapi.util.TextRange; @@ -68,7 +71,8 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; @@ -77,6 +81,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R static final String REFACTORING_NAME = RefactoringBundle.message("introduce.parameter.title"); private Project myProject; private JBPopup myEnclosingMethodsPopup; + private InplaceIntroduceParameterPopup myInplaceIntroduceParameterPopup; public void invoke(@NotNull final Project project, final Editor editor, PsiFile file, DataContext dataContext) { PsiDocumentManager.getInstance(project).commitAllDocuments(); @@ -334,7 +339,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R return method.hasModifierProperty(PsiModifier.ABSTRACT) && !method.getManager().isInProject(method); } - private static class Introducer { + private class Introducer { private final Project myProject; @@ -388,14 +393,28 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R Util.analyzeExpression(myExpr, localVars, classMemberRefs, params); } - if (myExpr instanceof PsiReferenceExpression) { - PsiElement resolved = ((PsiReferenceExpression)myExpr).resolve(); - if (resolved instanceof PsiLocalVariable) { - myLocalVar = (PsiLocalVariable) resolved; + final String propName = myLocalVar != null ? JavaCodeStyleManager + .getInstance(myProject).variableNameToPropertyName(myLocalVar.getName(), VariableKind.LOCAL_VARIABLE) : null; + final PsiType initializerType = IntroduceParameterProcessor.getInitializerType(null, myExpr, myLocalVar); + + TypeSelectorManagerImpl typeSelectorManager = myExpr != null + ? new TypeSelectorManagerImpl(myProject, initializerType, myExpr, occurences) + : new TypeSelectorManagerImpl(myProject, initializerType, occurences); + + NameSuggestionsGenerator nameSuggestionsGenerator = createNameSuggestionGenerator(myExpr, propName, myProject); + boolean isInplaceAvailableOnDataContext = myEditor != null && myEditor.getSettings().isVariableInplaceRenameEnabled(); + + if (isInplaceAvailableOnDataContext) { + myInplaceIntroduceParameterPopup = + new InplaceIntroduceParameterPopup(myProject, myEditor, classMemberRefs, + typeSelectorManager, + myExpr, myLocalVar, method, methodToSearchFor, occurences, + parametersToRemove, + mustBeFinal); + if (myInplaceIntroduceParameterPopup.startInplaceIntroduceTemplate()) { + return; } } - - if (ApplicationManager.getApplication().isUnitTestMode()) { @NonNls String parameterName = "anObject"; boolean replaceAllOccurences = true; @@ -405,26 +424,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R replaceAllOccurences, IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, mustBeFinal, false, null, parametersToRemove).run(); - } - else { - final String propName = myLocalVar != null ? JavaCodeStyleManager - .getInstance(myProject).variableNameToPropertyName(myLocalVar.getName(), VariableKind.LOCAL_VARIABLE) : null; - final PsiType initializerType = IntroduceParameterProcessor.getInitializerType(null, myExpr, myLocalVar); - - TypeSelectorManagerImpl typeSelectorManager = myExpr != null - ? new TypeSelectorManagerImpl(myProject, initializerType, myExpr, occurences) - : new TypeSelectorManagerImpl(myProject, initializerType, occurences); - - NameSuggestionsGenerator nameSuggestionsGenerator = createNameSuggestionGenerator(myExpr, propName, myProject); - boolean isInplaceAvailableOnDataContext = myEditor != null && myEditor.getSettings().isVariableInplaceRenameEnabled(); - - if (isInplaceAvailableOnDataContext && new InplaceIntroduceParameterPopup(myProject, myEditor, classMemberRefs, - typeSelectorManager, - myExpr, myLocalVar, method, methodToSearchFor, occurences, - parametersToRemove, - mustBeFinal).startInplaceIntroduceTemplate()) { - return; - } + } else { if (myEditor != null) { RefactoringUtil.highlightAllOccurences(myProject, occurences, myEditor); } @@ -437,5 +437,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase implements R } } - + public InplaceIntroduceParameterPopup getInplaceIntroduceParameterPopup() { + return myInplaceIntroduceParameterPopup; + } } diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceParameter/escapePosition.java b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/escapePosition.java new file mode 100644 index 000000000000..b1a33a400fb4 --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/escapePosition.java @@ -0,0 +1,6 @@ +class Test { + void simpleMethod() { + System.out.println(""); + System.out.println(""); + } +} diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceParameter/escapePositionOnLocal.java b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/escapePositionOnLocal.java new file mode 100644 index 000000000000..429535e3ac38 --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/escapePositionOnLocal.java @@ -0,0 +1,5 @@ +class Test { + void simpleMethod() { + boolean bb; + } +} diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceParameter/escapePositionOnLocal_after.java b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/escapePositionOnLocal_after.java new file mode 100644 index 000000000000..d7f32ec2711d --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/escapePositionOnLocal_after.java @@ -0,0 +1,5 @@ +class Test { + void simpleMethod() { + boolean bb; + } +} diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceParameter/escapePosition_after.java b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/escapePosition_after.java new file mode 100644 index 000000000000..fe58d5adc0c6 --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/escapePosition_after.java @@ -0,0 +1,6 @@ +class Test { + void simpleMethod() { + System.out.println(""); + System.out.println(""); + } +} diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll.java b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll.java new file mode 100644 index 000000000000..4300b299ca7f --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll.java @@ -0,0 +1,6 @@ +class Test { + void foo() { + System.out.println("hello"); + System.out.println("hello"); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll_after.java b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll_after.java new file mode 100644 index 000000000000..d596df5d9428 --- /dev/null +++ b/java/java-tests/testData/refactoring/inplaceIntroduceParameter/replaceAll_after.java @@ -0,0 +1,6 @@ +class Test { + void foo(String hello) { + System.out.println(hello); + System.out.println(hello); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java new file mode 100644 index 000000000000..29d229965fb0 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/refactoring/InplaceIntroduceParameterTest.java @@ -0,0 +1,135 @@ +/* + * Copyright 2000-2011 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 com.intellij.refactoring; + +import com.intellij.codeInsight.template.TemplateManager; +import com.intellij.codeInsight.template.impl.TemplateManagerImpl; +import com.intellij.codeInsight.template.impl.TemplateState; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pass; +import com.intellij.psi.PsiExpression; +import com.intellij.psi.PsiLocalVariable; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.introduceParameter.InplaceIntroduceParameterPopup; +import com.intellij.refactoring.introduceParameter.IntroduceParameterHandler; +import com.intellij.testFramework.LightCodeInsightTestCase; +import org.jetbrains.annotations.NotNull; + +/** + * User: anna + * Date: 3/16/11 + */ +public class InplaceIntroduceParameterTest extends LightCodeInsightTestCase { + + private static final String BASE_PATH = "/refactoring/inplaceIntroduceParameter/"; + + public void testReplaceAll() throws Exception { + doTest(new Pass() { + @Override + public void pass(InplaceIntroduceParameterPopup inplaceIntroduceFieldPopup) { + inplaceIntroduceFieldPopup.setReplaceAllOccurrences(true); + } + }); + } + + private void doTest(final Pass pass) throws Exception { + String name = getTestName(true); + configureByFile(BASE_PATH + name + ".java"); + final boolean enabled = getEditor().getSettings().isVariableInplaceRenameEnabled(); + TemplateManagerImpl templateManager = (TemplateManagerImpl)TemplateManager.getInstance(getProject()); + try { + templateManager.setTemplateTesting(true); + getEditor().getSettings().setVariableInplaceRenameEnabled(true); + + final MyIntroduceParameterHandler introduceParameterHandler = new MyIntroduceParameterHandler(); + final PsiExpression expression = + PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiExpression.class); + if (expression != null) { + introduceParameterHandler.invokeImpl(getProject(), expression, getEditor()); + } else { + final PsiLocalVariable localVariable = + PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiLocalVariable.class); + assertNotNull(localVariable); + introduceParameterHandler.invokeImpl(getProject(), localVariable, getEditor()); + } + pass.pass(introduceParameterHandler.getInplaceIntroduceParameterPopup()); + TemplateState state = TemplateManagerImpl.getTemplateState(getEditor()); + assert state != null; + state.gotoEnd(false); + checkResultByFile(BASE_PATH + name + "_after.java"); + } + finally { + myEditor.getSettings().setVariableInplaceRenameEnabled(enabled); + templateManager.setTemplateTesting(false); + } + } + + + + public void testEscapePosition() throws Exception { + doTestEscape(); + } + + public void testEscapePositionOnLocal() throws Exception { + doTestEscape(); + } + + private void doTestEscape() throws Exception { + String name = getTestName(true); + configureByFile(BASE_PATH + name + ".java"); + final boolean enabled = getEditor().getSettings().isVariableInplaceRenameEnabled(); + TemplateManagerImpl templateManager = (TemplateManagerImpl)TemplateManager.getInstance(getProject()); + try { + templateManager.setTemplateTesting(true); + getEditor().getSettings().setVariableInplaceRenameEnabled(true); + + final MyIntroduceParameterHandler introduceParameterHandler = new MyIntroduceParameterHandler(); + final PsiExpression expression = + PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiExpression.class); + if (expression != null) { + introduceParameterHandler.invokeImpl(getProject(), expression, getEditor()); + } else { + final PsiLocalVariable localVariable = + PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiLocalVariable.class); + assertNotNull(localVariable); + introduceParameterHandler.invokeImpl(getProject(), localVariable, getEditor()); + } + TemplateState state = TemplateManagerImpl.getTemplateState(getEditor()); + assert state != null; + state.gotoEnd(true); + checkResultByFile(BASE_PATH + name + "_after.java"); + } + finally { + myEditor.getSettings().setVariableInplaceRenameEnabled(enabled); + templateManager.setTemplateTesting(false); + } + } + + + private static class MyIntroduceParameterHandler extends IntroduceParameterHandler { + + @Override + public boolean invokeImpl(Project project, @NotNull PsiExpression selectedExpr, Editor editor) { + return super.invokeImpl(project, selectedExpr, editor); + } + + @Override + public boolean invokeImpl(Project project, PsiLocalVariable localVariable, Editor editor) { + return super.invokeImpl(project, localVariable, editor); + } + } +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java index 2f44d5e0c35d..0eff3ae90c2f 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java @@ -11,8 +11,6 @@ package com.intellij.refactoring; import com.intellij.JavaTestUtil; import com.intellij.codeInsight.CodeInsightUtil; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiLocalVariable; @@ -44,8 +42,11 @@ public class IntroduceParameterTest extends LightCodeInsightTestCase { private void doTest(int replaceFieldsWithGetters, boolean removeUnusedParameters, boolean searchForSuper, boolean declareFinal, final boolean generateDelegate, String conflict) throws Exception { + boolean enabled = true; try { configureByFile("/refactoring/introduceParameter/before" + getTestName(false) + ".java"); + enabled = myEditor.getSettings().isVariableInplaceRenameEnabled(); + myEditor.getSettings().setVariableInplaceRenameEnabled(false); perform(true, replaceFieldsWithGetters, "anObject", searchForSuper, declareFinal, removeUnusedParameters, generateDelegate); checkResultByFile("/refactoring/introduceParameter/after" + getTestName(false) + ".java"); if (conflict != null) { @@ -57,6 +58,8 @@ public class IntroduceParameterTest extends LightCodeInsightTestCase { throw e; } assertEquals(conflict, e.getMessage()); + } finally { + myEditor.getSettings().setVariableInplaceRenameEnabled(enabled); } } @@ -270,14 +273,23 @@ public class IntroduceParameterTest extends LightCodeInsightTestCase { private void doTestThroughHandler() throws Exception { configureByFile("/refactoring/introduceParameter/before" + getTestName(false) + ".java"); - new IntroduceParameterHandler().invoke(getProject(), myEditor, myFile, new DataContext() { - @Override - @Nullable - public Object getData(@NonNls final String dataId) { - return null; - } - }); - checkResultByFile("/refactoring/introduceParameter/after" + getTestName(false) + ".java"); + boolean enabled = true; + try { + configureByFile("/refactoring/introduceParameter/before" + getTestName(false) + ".java"); + enabled = myEditor.getSettings().isVariableInplaceRenameEnabled(); + myEditor.getSettings().setVariableInplaceRenameEnabled(false); + new IntroduceParameterHandler().invoke(getProject(), myEditor, myFile, new DataContext() { + @Override + @Nullable + public Object getData(@NonNls final String dataId) { + return null; + } + }); + checkResultByFile("/refactoring/introduceParameter/after" + getTestName(false) + ".java"); + } + finally { + myEditor.getSettings().setVariableInplaceRenameEnabled(enabled); + } } public void testEnclosingWithParamDeletion() throws Exception {