update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / refactoring / rename / JavaUnresolvableLocalCollisionDetector.java
blob0cf9705a508beb1f3348cec447ae142685844d0c
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.refactoring.rename;
18 import com.intellij.openapi.diagnostic.Logger;
19 import com.intellij.psi.*;
20 import com.intellij.psi.util.PsiTreeUtil;
21 import com.intellij.refactoring.util.RefactoringUtil;
22 import com.intellij.usageView.UsageInfo;
24 import java.util.List;
26 public class JavaUnresolvableLocalCollisionDetector {
27 private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.JavaUnresolvableLocalCollisionDetector");
29 private JavaUnresolvableLocalCollisionDetector() {
32 public static void findCollisions(final PsiElement element, final String newName, final List<UsageInfo> result) {
33 if (!(element instanceof PsiLocalVariable || element instanceof PsiParameter)) {
34 return;
38 PsiElement scope;
39 PsiElement anchor = null;
40 if (element instanceof PsiLocalVariable) {
41 scope = RefactoringUtil.getVariableScope((PsiLocalVariable)element);
42 if (!(element instanceof ImplicitVariable)) {
43 anchor = element.getParent();
46 else {
47 // element is a PsiParameter
48 scope = ((PsiParameter)element).getDeclarationScope();
50 LOG.assertTrue(scope != null);
52 final CollidingVariableVisitor collidingNameVisitor = new CollidingVariableVisitor() {
53 public void visitCollidingElement(PsiVariable collidingVariable) {
54 if (collidingVariable.equals(element) || collidingVariable instanceof PsiField) return;
55 LocalHidesRenamedLocalUsageInfo collision = new LocalHidesRenamedLocalUsageInfo(element, collidingVariable);
56 result.add(collision);
60 visitLocalsCollisions(element, newName, scope, anchor, collidingNameVisitor);
63 /*PsiElement place = scope.getLastChild();
64 PsiResolveHelper helper = place.getManager().getResolveHelper();
65 PsiVariable refVar = helper.resolveReferencedVariable(newName, place, null);
67 if (refVar != null) {
68 LocalHidesRenamedLocalUsageInfo collision = new LocalHidesRenamedLocalUsageInfo(element, refVar);
69 result.add(collision);
70 }*/
73 public static void visitLocalsCollisions(PsiElement element, final String newName,
74 PsiElement scope,
75 PsiElement place,
76 final CollidingVariableVisitor collidingNameVisitor) {
77 if (scope == null) return;
78 visitDownstreamCollisions(scope, place, newName, collidingNameVisitor);
79 visitUpstreamLocalCollisions(element, scope, newName, collidingNameVisitor);
82 private static void visitDownstreamCollisions(PsiElement scope, PsiElement place, final String newName,
83 final CollidingVariableVisitor collidingNameVisitor
84 ) {
85 ConflictingLocalVariablesVisitor collector =
86 new ConflictingLocalVariablesVisitor(newName, collidingNameVisitor);
87 if (place == null) {
88 scope.accept(collector);
90 else {
91 LOG.assertTrue(place.getParent() == scope);
92 for (PsiElement sibling = place; sibling != null; sibling = sibling.getNextSibling()) {
93 sibling.accept(collector);
99 public interface CollidingVariableVisitor {
100 void visitCollidingElement(PsiVariable collidingVariable);
103 private static void visitUpstreamLocalCollisions(PsiElement element, PsiElement scope,
104 String newName,
105 final CollidingVariableVisitor collidingNameVisitor) {
106 final PsiVariable collidingVariable =
107 JavaPsiFacade.getInstance(scope.getProject()).getResolveHelper().resolveReferencedVariable(newName, scope);
108 if (collidingVariable instanceof PsiLocalVariable || collidingVariable instanceof PsiParameter) {
109 final PsiElement commonParent = PsiTreeUtil.findCommonParent(element, collidingVariable);
110 if (commonParent != null) {
111 PsiElement current = element;
112 while (current != null && current != commonParent) {
113 if (current instanceof PsiMethod || current instanceof PsiClass) {
114 return;
116 current = current.getParent();
121 if (collidingVariable != null) {
122 collidingNameVisitor.visitCollidingElement(collidingVariable);
126 public static class ConflictingLocalVariablesVisitor extends JavaRecursiveElementWalkingVisitor {
127 protected final String myName;
128 protected CollidingVariableVisitor myCollidingNameVisitor;
130 public ConflictingLocalVariablesVisitor(String newName, CollidingVariableVisitor collidingNameVisitor) {
131 myName = newName;
132 myCollidingNameVisitor = collidingNameVisitor;
135 @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
136 visitElement(expression);
139 @Override public void visitClass(PsiClass aClass) {
142 @Override public void visitVariable(PsiVariable variable) {
143 if (myName.equals(variable.getName())) {
144 myCollidingNameVisitor.visitCollidingElement(variable);