update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / refactoring / move / MoveInstanceMembersUtil.java
blob2de506c22fd1fa6a6298d7cbc3d73f56ed588436
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.move;
18 import com.intellij.psi.*;
19 import com.intellij.psi.util.PsiTreeUtil;
20 import com.intellij.util.containers.HashSet;
21 import com.intellij.openapi.util.Pair;
23 import java.util.Set;
24 import java.util.Map;
25 import java.util.LinkedHashMap;
27 import org.jetbrains.annotations.Nullable;
29 /**
30 * @author ven
32 public class MoveInstanceMembersUtil {
33 /**
34 * @param member nonstatic class member to search for class references in
35 * @return Set<PsiMember> in result map may be null in case no member is needed, but class itself is.
37 public static Map<PsiClass, Set<PsiMember>> getThisClassesToMembers(final PsiMember member) {
38 Map<PsiClass, Set<PsiMember>> map = new LinkedHashMap<PsiClass, Set<PsiMember>>();
39 getThisClassesToMembers (member, map, member);
40 return map;
43 private static void getThisClassesToMembers(final PsiElement scope, final Map<PsiClass, Set<PsiMember>> map, final PsiMember refMember) {
44 if (scope instanceof PsiExpression) {
45 final PsiExpression expression = (PsiExpression)scope;
46 if (!(scope instanceof PsiReferenceExpression) || !((PsiReferenceExpression)scope).isReferenceTo(refMember)) {
47 final Pair<PsiMember, PsiClass> pair = getMemberAndClassReferencedByThis(expression);
48 if (pair != null) {
49 PsiClass refClass = pair.getSecond();
50 PsiMember member = pair.getFirst();
51 if (refClass != null && !PsiTreeUtil.isAncestor(refMember, member, false)) {
52 addReferencedMember(map, refClass, member);
56 if (expression instanceof PsiThisExpression) {
57 final PsiJavaCodeReferenceElement thisQualifier = ((PsiThisExpression)expression).getQualifier();
58 PsiClass thisClass = thisQualifier == null ? PsiTreeUtil.getParentOfType(expression, PsiClass.class, true) : ((PsiClass)thisQualifier.resolve());
59 if (thisClass != null) {
60 addReferencedMember(map, thisClass, null);
66 final PsiElement[] children = scope.getChildren();
67 for (PsiElement child : children) {
68 getThisClassesToMembers(child, map, refMember);
72 private static void addReferencedMember(final Map<PsiClass, Set<PsiMember>> map, final PsiClass classReferenced, final PsiMember member) {
73 Set<PsiMember> members = map.get(classReferenced);
74 if (members == null) {
75 members = new HashSet<PsiMember>();
76 map.put(classReferenced, members);
78 members.add(member);
81 @Nullable
82 private static Pair<PsiMember, PsiClass> getMemberAndClassReferencedByThis(final PsiExpression expression) {
83 if (expression instanceof PsiReferenceExpression) {
84 final PsiExpression qualifier = ((PsiReferenceExpression)expression).getQualifierExpression();
85 if (qualifier == null || qualifier instanceof PsiThisExpression) {
86 final PsiElement resolved = ((PsiReferenceExpression)expression).resolve();
87 if (resolved instanceof PsiMember && !((PsiMember)resolved).hasModifierProperty(PsiModifier.STATIC)) {
88 PsiClass referencedClass = getReferencedClass((PsiMember)resolved, qualifier, expression);
89 return new Pair<PsiMember, PsiClass>((PsiMember)resolved, referencedClass);
92 } else if (expression instanceof PsiNewExpression) {
93 final PsiNewExpression newExpression = (PsiNewExpression)expression;
94 final PsiExpression qualifier = newExpression.getQualifier();
95 if (qualifier == null || qualifier instanceof PsiThisExpression) {
96 PsiJavaCodeReferenceElement classReference = newExpression.getClassOrAnonymousClassReference();
97 if (classReference != null) {
98 final PsiClass resolved = (PsiClass)classReference.resolve();
99 if (resolved != null && !resolved.hasModifierProperty(PsiModifier.STATIC)) {
100 PsiClass referencedClass = getReferencedClass(resolved, qualifier, expression);
101 return new Pair<PsiMember, PsiClass>(resolved, referencedClass);
107 return null;
110 @Nullable
111 private static PsiClass getReferencedClass(final PsiMember member, final PsiExpression exprQualifier, final PsiExpression expression) {
112 if (exprQualifier != null) {
113 final PsiType type = exprQualifier.getType();
114 if (type instanceof PsiClassType) {
115 return ((PsiClassType)type).resolve();
117 return null;
118 } else {
119 PsiClass referencedClass = member.getContainingClass();
120 if (referencedClass == null) return null;
121 final PsiClass parentClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class);
122 assert parentClass != null;
123 if (!PsiTreeUtil.isAncestor(referencedClass, parentClass, false)) {
124 referencedClass = parentClass;
126 return referencedClass;
130 @Nullable
131 public static PsiClass getClassReferencedByThis(final PsiExpression expression) {
132 PsiClass enclosingClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class);
133 if (enclosingClass == null) return null;
134 final Pair<PsiMember, PsiClass> pair = getMemberAndClassReferencedByThis(expression);
135 if (pair != null) return pair.getSecond();
137 if (expression instanceof PsiThisExpression) {
138 final PsiJavaCodeReferenceElement thisQualifier = ((PsiThisExpression)expression).getQualifier();
139 if (thisQualifier == null) {
140 return enclosingClass;
142 else {
143 return (PsiClass)thisQualifier.resolve();
146 return null;