diff --git a/java/java-impl/src/com/intellij/refactoring/rename/JavaNameSuggestionProvider.java b/java/java-impl/src/com/intellij/refactoring/rename/JavaNameSuggestionProvider.java index 1b76bc6a3817..258826422a4c 100644 --- a/java/java-impl/src/com/intellij/refactoring/rename/JavaNameSuggestionProvider.java +++ b/java/java-impl/src/com/intellij/refactoring/rename/JavaNameSuggestionProvider.java @@ -22,6 +22,7 @@ import com.intellij.psi.codeStyle.NameUtil; import com.intellij.psi.codeStyle.SuggestedNameInfo; import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.usageView.UsageViewUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.ContainerUtil; @@ -33,48 +34,23 @@ public class JavaNameSuggestionProvider implements NameSuggestionProvider { @Nullable public SuggestedNameInfo getSuggestedNames(final PsiElement element, final PsiElement nameSuggestionContext, Set result) { String initialName = UsageViewUtil.getShortName(element); - SuggestedNameInfo info = suggestNamesForElement(element); + SuggestedNameInfo info = suggestNamesForElement(element, nameSuggestionContext); if (info != null) { info = JavaCodeStyleManager.getInstance(element.getProject()).suggestUniqueVariableName(info, element, true, true); } String parameterName = null; String superMethodName = null; - if (nameSuggestionContext != null) { + if (nameSuggestionContext instanceof PsiParameter) { final PsiElement nameSuggestionContextParent = nameSuggestionContext.getParent(); - if (nameSuggestionContextParent != null) { + if (nameSuggestionContextParent instanceof PsiParameterList) { final PsiElement parentOfParent = nameSuggestionContextParent.getParent(); - if (parentOfParent instanceof PsiExpressionList) { - final PsiExpressionList expressionList = (PsiExpressionList)parentOfParent; - final PsiElement parent = expressionList.getParent(); - if (parent instanceof PsiCallExpression) { - final PsiMethod method = ((PsiCallExpression)parent).resolveMethod(); - if (method != null) { - final PsiParameter[] parameters = method.getParameterList().getParameters(); - final PsiExpression[] expressions = expressionList.getExpressions(); - for (int i = 0; i < expressions.length; i++) { - PsiExpression expression = expressions[i]; - if (expression == nameSuggestionContextParent) { - if (i < parameters.length) { - parameterName = parameters[i].getName(); - } - break; - } - } - } - } - } - else if (parentOfParent instanceof PsiParameterList) { - final PsiElement parent3 = parentOfParent.getParent(); - if (parent3 instanceof PsiMethod) { - final String propName = PropertyUtil.getPropertyName((PsiMethod)parent3); - if (propName != null) { - parameterName = propName; - } - if (nameSuggestionContextParent instanceof PsiParameter) { - superMethodName = getSuperMethodName((PsiParameter) nameSuggestionContextParent, (PsiMethod) parent3); - } + if (parentOfParent instanceof PsiMethod) { + final String propName = PropertyUtil.getPropertyName((PsiMethod)parentOfParent); + if (propName != null) { + parameterName = propName; } + superMethodName = getSuperMethodName((PsiParameter) nameSuggestionContext, (PsiMethod) parentOfParent); } } } @@ -166,7 +142,7 @@ public class JavaNameSuggestionProvider implements NameSuggestionProvider { } @Nullable - private static SuggestedNameInfo suggestNamesForElement(final PsiElement element) { + private static SuggestedNameInfo suggestNamesForElement(final PsiElement element, PsiElement nameSuggestionContext) { PsiVariable var = null; if (element instanceof PsiVariable) { var = (PsiVariable)element; @@ -182,7 +158,13 @@ public class JavaNameSuggestionProvider implements NameSuggestionProvider { JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(element.getProject()); VariableKind variableKind = codeStyleManager.getVariableKind(var); - return codeStyleManager.suggestVariableName(variableKind, null, var.getInitializer(), var.getType()); + final SuggestedNameInfo nameInfo = codeStyleManager.suggestVariableName(variableKind, null, var.getInitializer(), var.getType()); + final PsiExpression expression = PsiTreeUtil.getParentOfType(nameSuggestionContext, PsiExpression.class, false); + if (expression != null) { + return new SuggestedNameInfo.Delegate(codeStyleManager.suggestVariableName(variableKind, null, expression, var.getType()).names, nameInfo); + + } + return nameInfo; } } diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameSuggestionsTest.groovy b/java/java-tests/testSrc/com/intellij/refactoring/RenameSuggestionsTest.groovy new file mode 100644 index 000000000000..23aff0a21167 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameSuggestionsTest.groovy @@ -0,0 +1,105 @@ +/* + * 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 com.intellij.refactoring +import com.intellij.codeInsight.TargetElementUtilBase +import com.intellij.codeInsight.lookup.LookupElement +import com.intellij.codeInsight.lookup.LookupEx +import com.intellij.codeInsight.lookup.LookupManager +import com.intellij.codeInsight.template.impl.TemplateManagerImpl +import com.intellij.codeInsight.template.impl.TemplateState +import com.intellij.psi.PsiElement +import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler +import com.intellij.testFramework.LightCodeInsightTestCase +/** + * User: anna + */ +class RenameSuggestionsTest extends LightCodeInsightTestCase { + public void "test by parameter name"() { + def text = """\ + class Test { + void foo(int foo) {} + { + int bar = 0; + foo(bar); + } + } + } + """ + + doTestSuggestionAvailable(text, "foo") + } + + public void "test by super parameter name"() { + def text = """\ + class Test { + void foo(int foo) {} + } + + class TestImpl extends Test { + void foo(int foo1) {} + } + } + """ + + doTestSuggestionAvailable(text, "foo") + } + + private doTestSuggestionAvailable(String text, String suggestion) { + configure text + def oldPreselectSetting = myEditor.settings.preselectRename + try { + TemplateManagerImpl.setTemplateTesting(getProject(), getTestRootDisposable()); + final PsiElement element = TargetElementUtilBase.findTargetElement(myEditor, TargetElementUtilBase.getInstance().getAllAccepted()) + + assertNotNull(element) + + VariableInplaceRenameHandler handler = new VariableInplaceRenameHandler() + + + handler.doRename(element, editor, null); + + LookupEx lookup = LookupManager.getActiveLookup(editor) + assertNotNull(lookup) + boolean found = false; + for (LookupElement item : lookup.items) { + if (item.getLookupString().equals(suggestion)) { + found = true + break + } + } + + if (!found) { + fail(suggestion + " not suggested") + } + } + catch (Exception e) { + e.printStackTrace() + } + finally { + myEditor.settings.preselectRename = oldPreselectSetting + + TemplateState state = TemplateManagerImpl.getTemplateState(editor) + + assertNotNull(state) + + state.gotoEnd(false) + } + } + + private def configure(String text) { + configureFromFileText("a.java", text) + } +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/InplaceVariableIntroducer.java b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/InplaceVariableIntroducer.java index 4d9bbd17b1ac..d60fbb6b0bd0 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/InplaceVariableIntroducer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/InplaceVariableIntroducer.java @@ -23,7 +23,6 @@ import com.intellij.codeInsight.template.impl.TemplateManagerImpl; import com.intellij.codeInsight.template.impl.TemplateState; import com.intellij.lang.ASTNode; import com.intellij.lang.LanguageTokenSeparatorGenerators; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.command.impl.StartMarkAction; @@ -172,7 +171,7 @@ public abstract class InplaceVariableIntroducer extends In @Override - protected MyLookupExpression createLookupExpression() { + protected MyLookupExpression createLookupExpression(PsiElement selectedElement) { return new MyIntroduceLookupExpression(getInitialName(), myNameSuggestions, myElementToRename, shouldSelectAll(), myAdvertisementText); } @@ -184,7 +183,7 @@ public abstract class InplaceVariableIntroducer extends In final PsiNamedElement elementToRename, final boolean shouldSelectAll, final String advertisementText) { - super(initialName, names, elementToRename, shouldSelectAll, advertisementText); + super(initialName, names, elementToRename, elementToRename, shouldSelectAll, advertisementText); myPointer = SmartPointerManager.getInstance(elementToRename.getProject()).createSmartPsiElementPointer(elementToRename); } 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 183ec0b4cc42..f61b94784ed7 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 @@ -236,8 +236,8 @@ public abstract class InplaceRefactoring { protected abstract boolean shouldSelectAll(); - protected MyLookupExpression createLookupExpression() { - return new MyLookupExpression(getInitialName(), myNameSuggestions, myElementToRename, shouldSelectAll(), myAdvertisementText); + protected MyLookupExpression createLookupExpression(PsiElement selectedElement) { + return new MyLookupExpression(getInitialName(), myNameSuggestions, myElementToRename, selectedElement, shouldSelectAll(), myAdvertisementText); } protected boolean acceptReference(PsiReference reference) { @@ -274,7 +274,7 @@ public abstract class InplaceRefactoring { boolean hasReferenceOnNameIdentifier = false; for (PsiReference ref : refs) { if (isReferenceAtCaret(selectedElement, ref)) { - builder.replaceElement(ref, PRIMARY_VARIABLE_NAME, createLookupExpression(), true); + builder.replaceElement(ref, PRIMARY_VARIABLE_NAME, createLookupExpression(selectedElement), true); subrefOnPrimaryElement = true; continue; } @@ -626,7 +626,7 @@ public abstract class InplaceRefactoring { int offset) { final PsiElement element = reference.getElement(); if (element == selectedElement && checkRangeContainsOffset(offset, reference.getRangeInElement(), element)) { - builder.replaceElement(reference, PRIMARY_VARIABLE_NAME, createLookupExpression(), true); + builder.replaceElement(reference, PRIMARY_VARIABLE_NAME, createLookupExpression(selectedElement), true); } else { builder.replaceElement(reference, OTHER_VARIABLE_NAME, PRIMARY_VARIABLE_NAME, false); @@ -644,7 +644,7 @@ public abstract class InplaceRefactoring { final PsiElement selectedElement, final TemplateBuilderImpl builder) { if (element == selectedElement) { - builder.replaceElement(element, PRIMARY_VARIABLE_NAME, createLookupExpression(), true); + builder.replaceElement(element, PRIMARY_VARIABLE_NAME, createLookupExpression(myElementToRename), true); } else if (textRange != null) { builder.replaceElement(element, textRange, OTHER_VARIABLE_NAME, PRIMARY_VARIABLE_NAME, false); diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MyLookupExpression.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MyLookupExpression.java index 06360cb4f56d..9874230b539b 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MyLookupExpression.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MyLookupExpression.java @@ -28,6 +28,7 @@ import com.intellij.codeInsight.template.impl.TemplateState; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.codeStyle.SuggestedNameInfo; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; @@ -48,21 +49,23 @@ public class MyLookupExpression extends Expression { public MyLookupExpression(final String name, final LinkedHashSet names, - final PsiNamedElement elementToRename, + PsiNamedElement elementToRename, + final PsiElement nameSuggestionContext, final boolean shouldSelectAll, final String advertisement) { myName = name; myAdvertisementText = advertisement; - myLookupItems = initLookupItems(names, elementToRename, shouldSelectAll); + myLookupItems = initLookupItems(names, elementToRename, nameSuggestionContext, shouldSelectAll); } private static LookupElement[] initLookupItems(LinkedHashSet names, - PsiNamedElement elementToRename, + PsiNamedElement elementToRename, + PsiElement nameSuggestionContext, final boolean shouldSelectAll) { if (names == null) { names = new LinkedHashSet(); for (NameSuggestionProvider provider : Extensions.getExtensions(NameSuggestionProvider.EP_NAME)) { - final SuggestedNameInfo suggestedNameInfo = provider.getSuggestedNames(elementToRename, elementToRename, names); + final SuggestedNameInfo suggestedNameInfo = provider.getSuggestedNames(elementToRename, nameSuggestionContext, names); if (suggestedNameInfo != null && provider instanceof PreferrableNameSuggestionProvider && !((PreferrableNameSuggestionProvider)provider).shouldCheckOthers()) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/other/GrAliasImportIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/other/GrAliasImportIntention.java index 3112af6fe3e0..4663ef6d305f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/other/GrAliasImportIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/other/GrAliasImportIntention.java @@ -139,7 +139,7 @@ public class GrAliasImportIntention extends Intention { final PsiElement aliasNameElement = templateImport.getAliasNameElement(); assert aliasNameElement != null; - templateBuilder.replaceElement(aliasNameElement, new MyLookupExpression(resolved.getName(), names, (PsiNamedElement)resolved, true, null)); + templateBuilder.replaceElement(aliasNameElement, new MyLookupExpression(resolved.getName(), names, (PsiNamedElement)resolved, resolved, true, null)); Template built = templateBuilder.buildTemplate(); final Editor newEditor = QuickfixUtil.positionCursor(project, file, templateImport);