class members refactoring refactoring
[fedora-idea.git] / lang-impl / src / com / intellij / refactoring / classMembers / AbstractMemberInfoStorage.java
blobe9ebbde63477343e4d192082bb63ee29aa413075
1 package com.intellij.refactoring.classMembers;
3 import com.intellij.psi.PsiElement;
4 import com.intellij.util.containers.HashMap;
6 import java.util.*;
8 /**
9 * @author Dennis.Ushakov
11 public abstract class AbstractMemberInfoStorage<T extends PsiElement, C extends PsiElement, M extends MemberInfoBase<T>> {
12 protected final HashMap<C, LinkedHashSet<C>> myClassToSubclassesMap = new HashMap<C, LinkedHashSet<C>>();
13 private final HashMap<C, Set<C>> myTargetClassToExtendingMap = new HashMap<C, Set<C>>();
14 private final HashMap<C, List<M>> myClassToMemberInfoMap = new HashMap<C, List<M>>();
15 private final C myClass;
16 protected final MemberInfoBase.Filter<T> myFilter;
17 private final HashMap<C, List<M>> myTargetClassToMemberInfosMap = new HashMap<C, List<M>>();
18 private final HashMap<C, LinkedHashSet<M>> myTargetClassToMemberInfosListMap = new HashMap<C, LinkedHashSet<M>>();
19 private final HashMap<C, HashSet<M>> myTargetClassToDuplicatedMemberInfosMap = new HashMap<C, HashSet<M>>();
21 public AbstractMemberInfoStorage(C aClass, MemberInfoBase.Filter<T> memberInfoFilter) {
22 myClass = aClass;
23 buildSubClassesMap(aClass);
24 myFilter = memberInfoFilter;
27 private Set<C> getAllClasses() {
28 return myClassToSubclassesMap.keySet();
31 public Set<C> getExtending(C baseClass) {
32 Set<C> result = myTargetClassToExtendingMap.get(baseClass);
33 if(result == null) {
34 result = new HashSet<C>();
35 result.add(baseClass);
36 final Set<C> allClasses = getAllClasses();
37 for (C aClass : allClasses) {
38 if (isInheritor(baseClass, aClass)) {
39 result.add(aClass);
42 myTargetClassToExtendingMap.put(baseClass, result);
45 return result;
48 protected abstract boolean isInheritor(C baseClass, C aClass);
50 protected abstract void buildSubClassesMap(C aClass);
52 public List<M> getClassMemberInfos(C aClass) {
53 List<M> result = myClassToMemberInfoMap.get(aClass);
54 if(result == null) {
55 ArrayList<M> temp = new ArrayList<M>();
56 extractClassMembers(aClass, temp);
57 result = Collections.unmodifiableList(temp);
58 myClassToMemberInfoMap.put(aClass, result);
60 return result;
63 protected abstract void extractClassMembers(C aClass, ArrayList<M> temp);
65 public List<M> getMemberInfosList(C baseClass) {
66 List<M> result = myTargetClassToMemberInfosMap.get(baseClass);
68 if (result == null) {
69 Set<M> list = getIntermediateClassesMemberInfosList(baseClass);
70 result = Collections.unmodifiableList(new ArrayList<M>(list));
71 myTargetClassToMemberInfosMap.put(baseClass, result);
74 return result;
77 private Set<M> getIntermediateClassesMemberInfosList(C targetClass) {
78 LinkedHashSet<M> result = myTargetClassToMemberInfosListMap.get(targetClass);
79 if(result == null) {
80 result = new LinkedHashSet<M>();
81 Set<C> subclasses = getSubclasses(targetClass);
82 for (C subclass : subclasses) {
83 List<M> memberInfos = getClassMemberInfos(subclass);
84 result.addAll(memberInfos);
86 for (C subclass : subclasses) {
87 result.addAll(getIntermediateClassesMemberInfosList(subclass));
89 myTargetClassToMemberInfosListMap.put(targetClass, result);
91 return result;
94 protected LinkedHashSet<C> getSubclasses(C aClass) {
95 LinkedHashSet<C> result = myClassToSubclassesMap.get(aClass);
96 if(result == null) {
97 result = new LinkedHashSet<C>();
98 myClassToSubclassesMap.put(aClass, result);
100 return result;
103 public Set<M> getDuplicatedMemberInfos(C baseClass) {
104 HashSet<M> result = myTargetClassToDuplicatedMemberInfosMap.get(baseClass);
106 if(result == null) {
107 result = buildDuplicatedMemberInfos(baseClass);
108 myTargetClassToDuplicatedMemberInfosMap.put(baseClass, result);
110 return result;
113 private HashSet<M> buildDuplicatedMemberInfos(C baseClass) {
114 HashSet<M> result = new HashSet<M>();
115 List<M> memberInfos = getMemberInfosList(baseClass);
117 for (int i = 0; i < memberInfos.size(); i++) {
118 final M memberInfo = memberInfos.get(i);
119 final PsiElement member = memberInfo.getMember();
121 for(int j = 0; j < i; j++) {
122 final M memberInfo1 = memberInfos.get(j);
123 final PsiElement member1 = memberInfo1.getMember();
124 if(memberConflict(member1, member)) {
125 result.add(memberInfo);
126 // We let the first one be...
127 // result.add(memberInfo1);
131 return result;
134 protected abstract boolean memberConflict(PsiElement member1, PsiElement member);