diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java index 300a9472a3cb..15e09d1caa46 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java @@ -91,12 +91,24 @@ public class PsiResolveHelperImpl implements PsiResolveHelper { } public PsiVariable resolveReferencedVariable(@NotNull String referenceText, PsiElement context) { + return resolveVar(referenceText, context, null); + } + + @Override + public PsiVariable resolveAccessibleReferencedVariable(@NotNull String referenceText, PsiElement context) { + final boolean[] problemWithAccess = new boolean[1]; + PsiVariable variable = resolveVar(referenceText, context, problemWithAccess); + return problemWithAccess[0] ? null : variable; + } + + @Nullable + private PsiVariable resolveVar(String referenceText, PsiElement context, boolean[] problemWithAccess) { final FileElement holderElement = DummyHolderFactory.createHolder(myManager, context).getTreeElement(); TreeElement ref = Parsing.parseJavaCodeReferenceText(myManager, referenceText, holderElement.getCharTable()); if (ref == null) return null; holderElement.rawAddChildren(ref); PsiJavaCodeReferenceElement psiRef = (PsiJavaCodeReferenceElement)SourceTreeToPsiMap.treeElementToPsi(ref); - return ResolveVariableUtil.resolveVariable(psiRef, null, null); + return ResolveVariableUtil.resolveVariable(psiRef, problemWithAccess, null); } public boolean isAccessible(@NotNull PsiMember member, @NotNull PsiElement place, @Nullable PsiClass accessObjectClass) { diff --git a/java/java-impl/src/com/intellij/refactoring/rename/JavaUnresolvableLocalCollisionDetector.java b/java/java-impl/src/com/intellij/refactoring/rename/JavaUnresolvableLocalCollisionDetector.java index d4a47b303bf4..2068ae96757d 100644 --- a/java/java-impl/src/com/intellij/refactoring/rename/JavaUnresolvableLocalCollisionDetector.java +++ b/java/java-impl/src/com/intellij/refactoring/rename/JavaUnresolvableLocalCollisionDetector.java @@ -104,7 +104,7 @@ public class JavaUnresolvableLocalCollisionDetector { String newName, final CollidingVariableVisitor collidingNameVisitor) { final PsiVariable collidingVariable = - JavaPsiFacade.getInstance(scope.getProject()).getResolveHelper().resolveReferencedVariable(newName, scope); + JavaPsiFacade.getInstance(scope.getProject()).getResolveHelper().resolveAccessibleReferencedVariable(newName, scope); if (collidingVariable instanceof PsiLocalVariable || collidingVariable instanceof PsiParameter) { final PsiElement commonParent = PsiTreeUtil.findCommonParent(element, collidingVariable); if (commonParent != null) { diff --git a/java/java-impl/src/com/intellij/refactoring/util/FieldConflictsResolver.java b/java/java-impl/src/com/intellij/refactoring/util/FieldConflictsResolver.java index 974568a2a324..1d16b343cda7 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/FieldConflictsResolver.java +++ b/java/java-impl/src/com/intellij/refactoring/util/FieldConflictsResolver.java @@ -49,7 +49,7 @@ public class FieldConflictsResolver { return; } JavaPsiFacade facade = JavaPsiFacade.getInstance(myScope.getProject()); - final PsiVariable oldVariable = facade.getResolveHelper().resolveReferencedVariable(name, myScope); + final PsiVariable oldVariable = facade.getResolveHelper().resolveAccessibleReferencedVariable(name, myScope); myField = oldVariable instanceof PsiField ? (PsiField) oldVariable : null; if (!(oldVariable instanceof PsiField)) { myReferenceExpressions = null; diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java index 335a83396126..ca14ee175c2c 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java @@ -117,7 +117,7 @@ public class RefactoringUtil { final String fieldName = newField.getName(); final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject()); final PsiElement element = occurrence.getUserData(ElementToWorkOn.PARENT); - final PsiVariable psiVariable = facade.getResolveHelper().resolveReferencedVariable(fieldName, element != null ? element : occurrence); + final PsiVariable psiVariable = facade.getResolveHelper().resolveAccessibleReferencedVariable(fieldName, element != null ? element : occurrence); final PsiElementFactory factory = facade.getElementFactory(); if (psiVariable != null && psiVariable.equals(newField)) { return IntroduceVariableBase.replace(occurrence, factory.createExpressionFromText(fieldName, null), manager.getProject()); @@ -143,7 +143,7 @@ public class RefactoringUtil { index++; final PsiManager manager = place.getManager(); PsiResolveHelper helper = JavaPsiFacade.getInstance(manager.getProject()).getResolveHelper(); - PsiVariable refVar = helper.resolveReferencedVariable(name, place); + PsiVariable refVar = helper.resolveAccessibleReferencedVariable(name, place); if (refVar != null && !manager.areElementsEquivalent(refVar, fieldToReplace)) continue; class CancelException extends RuntimeException { } diff --git a/java/java-tests/testData/refactoring/introduceVariable/NonConflictingField.after.java b/java/java-tests/testData/refactoring/introduceVariable/NonConflictingField.after.java new file mode 100644 index 000000000000..d9859f406561 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/NonConflictingField.after.java @@ -0,0 +1,9 @@ +class Base { + private int name = 0; +} + +class Child extends Base { + void foo() { + int name = 1; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/NonConflictingField.java b/java/java-tests/testData/refactoring/introduceVariable/NonConflictingField.java new file mode 100644 index 000000000000..472122a0a329 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/NonConflictingField.java @@ -0,0 +1,9 @@ +class Base { + private int name = 0; +} + +class Child extends Base { + void foo() { + 1 + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java index 3c9fd3920fec..d65e237873a7 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java @@ -93,6 +93,10 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { doTest(new MockIntroduceVariableHandler("name", false, false, true, "int")); } + public void testNonConflictingField() throws Exception { + doTest(new MockIntroduceVariableHandler("name", false, false, true, "int")); + } + public void testScr16910() throws Exception { doTest(new MockIntroduceVariableHandler("i", true, true, false, "int")); } diff --git a/java/openapi/src/com/intellij/psi/PsiResolveHelper.java b/java/openapi/src/com/intellij/psi/PsiResolveHelper.java index 86db81abf090..e0aca79f4455 100644 --- a/java/openapi/src/com/intellij/psi/PsiResolveHelper.java +++ b/java/openapi/src/com/intellij/psi/PsiResolveHelper.java @@ -85,6 +85,17 @@ public interface PsiResolveHelper { @Nullable PsiVariable resolveReferencedVariable(@NotNull String referenceText, PsiElement context); + /** + * Resolves a reference to a variable, given the text of the reference and the context + * in which it was encountered. + * + * @param referenceText the text of the reference. + * @param context the context in which the reference is found. + * @return the resolve result, or null if the resolve was not successful or resolved variable is not accessible in a given context. + */ + @Nullable + PsiVariable resolveAccessibleReferencedVariable(@NotNull String referenceText, PsiElement context); + boolean isAccessible(@NotNull PsiMember member, @Nullable PsiModifierList modifierList, @NotNull PsiElement place, @Nullable PsiClass accessObjectClass, @Nullable PsiElement currentFileResolveScope); diff --git a/java/openapi/src/com/intellij/psi/util/PsiUtil.java b/java/openapi/src/com/intellij/psi/util/PsiUtil.java index cbb99a2868a2..4d2364ba11c9 100644 --- a/java/openapi/src/com/intellij/psi/util/PsiUtil.java +++ b/java/openapi/src/com/intellij/psi/util/PsiUtil.java @@ -174,7 +174,7 @@ public final class PsiUtil extends PsiUtilBase { public static boolean isVariableNameUnique(@NotNull String name, @NotNull PsiElement place) { PsiResolveHelper helper = JavaPsiFacade.getInstance(place.getProject()).getResolveHelper(); - return helper.resolveReferencedVariable(name, place) == null; + return helper.resolveAccessibleReferencedVariable(name, place) == null; } /** diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduceParameter/java2groovy/FieldConflictsResolver.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduceParameter/java2groovy/FieldConflictsResolver.java index 73ed97f1d70c..53c2b826a7a8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduceParameter/java2groovy/FieldConflictsResolver.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduceParameter/java2groovy/FieldConflictsResolver.java @@ -50,7 +50,7 @@ public class FieldConflictsResolver { return; } JavaPsiFacade facade = JavaPsiFacade.getInstance(myScope.getProject()); - final PsiVariable oldVariable = facade.getResolveHelper().resolveReferencedVariable(name, myScope); + final PsiVariable oldVariable = facade.getResolveHelper().resolveAccessibleReferencedVariable(name, myScope); myField = oldVariable instanceof PsiField ? (PsiField)oldVariable : null; if (!(oldVariable instanceof PsiField)) {