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
.classMembers
;
18 import com
.intellij
.psi
.*;
19 import com
.intellij
.refactoring
.RefactoringBundle
;
20 import com
.intellij
.refactoring
.classMembers
.MemberDependencyGraph
;
21 import com
.intellij
.util
.containers
.HashMap
;
23 import java
.util
.HashSet
;
24 import java
.util
.Iterator
;
27 public class InterfaceMemberDependencyGraph
implements MemberDependencyGraph
<PsiMember
, MemberInfo
> {
28 protected HashSet
<PsiMethod
> myInterfaceDependencies
= null;
29 protected HashMap
<PsiMethod
,HashSet
<PsiClass
>> myMembersToInterfacesMap
= new HashMap
<PsiMethod
, HashSet
<PsiClass
>>();
30 protected HashSet
<PsiClass
> myImplementedInterfaces
;
31 protected HashMap
<PsiClass
,HashSet
<PsiMethod
>> myMethodsFromInterfaces
;
32 protected PsiClass myClass
;
34 public InterfaceMemberDependencyGraph(PsiClass aClass
) {
36 myImplementedInterfaces
= new HashSet
<PsiClass
>();
37 myMethodsFromInterfaces
= new com
.intellij
.util
.containers
.HashMap
<PsiClass
, HashSet
<PsiMethod
>>();
40 public void memberChanged(MemberInfo memberInfo
) {
41 if (ClassMembersUtil
.isImplementedInterface(memberInfo
)) {
42 final PsiClass aClass
= (PsiClass
) memberInfo
.getMember();
43 myInterfaceDependencies
= null;
44 myMembersToInterfacesMap
= null;
45 if(memberInfo
.isChecked()) {
46 myImplementedInterfaces
.add(aClass
);
49 myImplementedInterfaces
.remove(aClass
);
54 public Set
<?
extends PsiMember
> getDependent() {
55 if(myInterfaceDependencies
== null) {
56 myInterfaceDependencies
= new HashSet
<PsiMethod
>();
57 myMembersToInterfacesMap
= new com
.intellij
.util
.containers
.HashMap
<PsiMethod
, HashSet
<PsiClass
>>();
58 for (final PsiClass implementedInterface
: myImplementedInterfaces
) {
59 addInterfaceDeps(implementedInterface
);
62 return myInterfaceDependencies
;
65 public Set
<?
extends PsiMember
> getDependenciesOf(PsiMember member
) {
66 final Set dependent
= getDependent();
67 if(dependent
.contains(member
)) return myMembersToInterfacesMap
.get(member
);
71 public String
getElementTooltip(PsiMember member
) {
72 final Set
<?
extends PsiMember
> dependencies
= getDependenciesOf(member
);
73 if(dependencies
== null || dependencies
.size() == 0) return null;
74 StringBuffer buffer
= new StringBuffer();
75 buffer
.append(RefactoringBundle
.message("interface.member.dependency.required.by.interfaces", dependencies
.size()));
77 for (Iterator
<?
extends PsiMember
> iterator
= dependencies
.iterator(); iterator
.hasNext();) {
78 PsiClass aClass
= (PsiClass
) iterator
.next();
79 buffer
.append(aClass
.getName());
80 if(iterator
.hasNext()) {
84 return buffer
.toString();
87 protected void addInterfaceDeps(PsiClass intf
) {
88 HashSet
<PsiMethod
> interfaceMethods
= myMethodsFromInterfaces
.get(intf
);
90 if(interfaceMethods
== null) {
91 interfaceMethods
= new HashSet
<PsiMethod
>();
92 buildInterfaceMethods(interfaceMethods
, intf
);
93 myMethodsFromInterfaces
.put(intf
, interfaceMethods
);
95 for (PsiMethod method
: interfaceMethods
) {
96 HashSet
<PsiClass
> interfaces
= myMembersToInterfacesMap
.get(method
);
97 if (interfaces
== null) {
98 interfaces
= new HashSet
<PsiClass
>();
99 myMembersToInterfacesMap
.put(method
, interfaces
);
101 interfaces
.add(intf
);
103 myInterfaceDependencies
.addAll(interfaceMethods
);
106 private void buildInterfaceMethods(HashSet
<PsiMethod
> interfaceMethods
, PsiClass intf
) {
107 PsiMethod
[] methods
= intf
.getMethods();
108 for (PsiMethod method1
: methods
) {
109 PsiMethod method
= myClass
.findMethodBySignature(method1
, true);
110 if (method
!= null) {
111 interfaceMethods
.add(method
);
115 PsiReferenceList implementsList
= intf
.getImplementsList();
116 if (implementsList
!= null) {
117 PsiClassType
[] implemented
= implementsList
.getReferencedTypes();
118 for (PsiClassType aImplemented
: implemented
) {
119 PsiClass resolved
= aImplemented
.resolve();
120 if (resolved
!= null) {
121 buildInterfaceMethods(interfaceMethods
, resolved
);
126 PsiReferenceList extendsList
= intf
.getExtendsList();
127 if (extendsList
!= null) {
128 PsiClassType
[] extended
= extendsList
.getReferencedTypes();
129 for (PsiClassType aExtended
: extended
) {
130 PsiClass ref
= aExtended
.resolve();
132 buildInterfaceMethods(interfaceMethods
, ref
);