rename: detect "field would hide local" conflict (IDEA-125934)

This commit is contained in:
Anna Kozlova
2014-06-05 16:05:50 +04:00
parent 0de6aa98ab
commit 350760c993
5 changed files with 84 additions and 0 deletions
@@ -0,0 +1,44 @@
/*
* 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.
* 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.
*/
/*
* Created by IntelliJ IDEA.
* User: dsl
* Date: 05.06.2002
* Time: 12:43:27
* To change template for new class use
* Code Style | Class Templates options (Tools | IDE Options).
*/
package com.intellij.refactoring.rename;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.RefactoringUIUtil;
import com.intellij.usageView.UsageViewUtil;
public class FieldHidesLocalUsageInfo extends UnresolvableCollisionUsageInfo {
public FieldHidesLocalUsageInfo(PsiElement element, PsiElement referencedElement) {
super(element, referencedElement);
}
public String getDescription() {
String descr = RefactoringBundle.message("local.will.be.hidden.renamed",
RefactoringUIUtil.getDescription(getElement(), true));
return CommonRefactoringUtil.capitalize(descr);
}
}
@@ -24,9 +24,11 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.controlFlow.ControlFlowUtil;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.search.searches.OverridingMethodsSearch;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.JavaRefactoringSettings;
@@ -350,6 +352,18 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
PsiField conflictingField = inheritor.findFieldByName(newName, false);
if (conflictingField != null) {
result.add(new SubmemberHidesMemberUsageInfo(conflictingField, field));
}
else { //local class
final PsiMember member = PsiTreeUtil.getParentOfType(inheritor, PsiMember.class);
if (member != null) {
final ArrayList<PsiVariable> variables = new ArrayList<PsiVariable>();
ControlFlowUtil.collectOuterLocals(variables, inheritor, inheritor, member);
for (PsiVariable variable : variables) {
if (newName.equals(variable.getName())) {
result.add(new FieldHidesLocalUsageInfo(variable, field));
}
}
}
}
}
}
@@ -0,0 +1,14 @@
class A4 {
protected final int <caret>a = 1;
}
class B {
void main() {
final int b = 2;
new A4() {
void m() {
System.out.println(b);
}
};
}
}
@@ -193,6 +193,17 @@ public class RenameCollisionsTest extends LightRefactoringTestCase {
fail("Conflicts were not found");
}
public void testFieldHidesLocal() throws Exception {
try {
doTest("b");
}
catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
Assert.assertEquals("Renamed field will hide local variable <b><code>b</code></b>", e.getMessage());
return;
}
fail("Conflicts were not found");
}
public void testRenameMethodNoCollisionWithOtherSignature() throws Exception {
doTest("foo2");
}