update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / refactoring / util / FieldConflictsResolver.java
blob9fbea01ed06be5633ae0fe09a6289577e578cf6c
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.util;
18 import com.intellij.openapi.diagnostic.Logger;
19 import com.intellij.psi.*;
20 import com.intellij.psi.codeStyle.CodeStyleManager;
21 import com.intellij.psi.search.LocalSearchScope;
22 import com.intellij.psi.search.searches.ReferencesSearch;
23 import com.intellij.psi.util.InheritanceUtil;
24 import com.intellij.psi.util.PsiTreeUtil;
25 import com.intellij.util.IncorrectOperationException;
26 import org.jetbrains.annotations.Nullable;
28 import java.util.ArrayList;
29 import java.util.List;
31 /**
32 * Resolves conflicts with fields in a class, when new local variable is
33 * introduced in code block
34 * @author dsl
36 public class FieldConflictsResolver {
37 private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.FieldConflictsResolver");
38 private final PsiCodeBlock myScope;
39 private final PsiField myField;
40 private final List<PsiReferenceExpression> myReferenceExpressions;
41 private PsiClass myQualifyingClass;
43 public FieldConflictsResolver(String name, PsiCodeBlock scope) {
44 myScope = scope;
45 if (myScope == null) {
46 myField = null;
47 myReferenceExpressions = null;
48 return;
50 JavaPsiFacade facade = JavaPsiFacade.getInstance(myScope.getProject());
51 final PsiVariable oldVariable = facade.getResolveHelper().resolveReferencedVariable(name, myScope);
52 myField = oldVariable instanceof PsiField ? (PsiField) oldVariable : null;
53 if (!(oldVariable instanceof PsiField)) {
54 myReferenceExpressions = null;
55 return;
57 myReferenceExpressions = new ArrayList<PsiReferenceExpression>();
58 for (PsiReference reference : ReferencesSearch.search(myField, new LocalSearchScope(myScope), false)) {
59 final PsiElement element = reference.getElement();
60 if (element instanceof PsiReferenceExpression) {
61 final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)element;
62 if (referenceExpression.getQualifierExpression() == null) {
63 myReferenceExpressions.add(referenceExpression);
67 if (myField.hasModifierProperty(PsiModifier.STATIC)) {
68 myQualifyingClass = myField.getContainingClass();
72 public PsiExpression fixInitializer(PsiExpression initializer) {
73 if (myField == null) return initializer;
74 final PsiReferenceExpression[] replacedRef = {null};
75 initializer.accept(new JavaRecursiveElementVisitor() {
76 @Override
77 public void visitReferenceExpression(PsiReferenceExpression expression) {
78 final PsiExpression qualifierExpression = expression.getQualifierExpression();
79 if (qualifierExpression != null) {
80 qualifierExpression.accept(this);
82 else {
83 final PsiElement result = expression.resolve();
84 if (expression.getManager().areElementsEquivalent(result, myField)) {
85 try {
86 replacedRef[0] = qualifyReference(expression, myField, myQualifyingClass);
88 catch (IncorrectOperationException e) {
89 LOG.error(e);
94 });
95 if (!initializer.isValid()) return replacedRef[0];
96 return initializer;
99 public void fix() throws IncorrectOperationException {
100 if (myField == null) return;
101 final PsiManager manager = myScope.getManager();
102 for (PsiReferenceExpression referenceExpression : myReferenceExpressions) {
103 if (!referenceExpression.isValid()) continue;
104 final PsiElement newlyResolved = referenceExpression.resolve();
105 if (!manager.areElementsEquivalent(newlyResolved, myField)) {
106 qualifyReference(referenceExpression, myField, myQualifyingClass);
112 public static PsiReferenceExpression qualifyReference(PsiReferenceExpression referenceExpression,
113 final PsiMember member,
114 @Nullable final PsiClass qualifyingClass) throws IncorrectOperationException {
115 PsiManager manager = referenceExpression.getManager();
116 PsiReferenceExpression expressionFromText;
117 final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
118 if (qualifyingClass == null) {
119 PsiClass parentClass = PsiTreeUtil.getParentOfType(referenceExpression, PsiClass.class);
120 final PsiClass containingClass = member.getContainingClass();
121 if (parentClass != null && !InheritanceUtil.isInheritorOrSelf(parentClass, containingClass, true)) {
122 while (parentClass != null && !InheritanceUtil.isInheritorOrSelf(parentClass, containingClass, true)) {
123 parentClass = PsiTreeUtil.getParentOfType(parentClass, PsiClass.class, true);
125 LOG.assertTrue(parentClass != null);
126 expressionFromText = (PsiReferenceExpression)factory.createExpressionFromText("A.this." + member.getName(), null);
127 ((PsiThisExpression)expressionFromText.getQualifierExpression()).getQualifier().replace(factory.createClassReferenceElement(parentClass));
129 else {
130 expressionFromText = (PsiReferenceExpression)factory.createExpressionFromText("this." + member.getName(), null);
133 else {
134 expressionFromText = (PsiReferenceExpression)factory.createExpressionFromText("A." + member.getName(), null);
135 expressionFromText.setQualifierExpression(factory.createReferenceExpression(qualifyingClass));
137 CodeStyleManager codeStyleManager = manager.getCodeStyleManager();
138 expressionFromText = (PsiReferenceExpression)codeStyleManager.reformat(expressionFromText);
139 return (PsiReferenceExpression)referenceExpression.replace(expressionFromText);