1 11 package org.eclipse.jdt.internal.corext.refactoring.rename; 12 13 import java.util.ArrayList ; 14 import java.util.HashSet ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 import java.util.Set ; 18 19 import org.eclipse.core.runtime.IProgressMonitor; 20 import org.eclipse.core.runtime.NullProgressMonitor; 21 import org.eclipse.core.runtime.OperationCanceledException; 22 import org.eclipse.core.runtime.SubProgressMonitor; 23 24 import org.eclipse.jdt.core.IMethod; 25 import org.eclipse.jdt.core.IType; 26 import org.eclipse.jdt.core.ITypeHierarchy; 27 import org.eclipse.jdt.core.JavaModelException; 28 import org.eclipse.jdt.core.WorkingCopyOwner; 29 30 import org.eclipse.jdt.internal.corext.Assert; 31 import org.eclipse.jdt.internal.corext.refactoring.Checks; 32 import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; 33 import org.eclipse.jdt.internal.corext.util.JdtFlags; 34 35 41 public class RippleMethodFinder { 42 43 private RippleMethodFinder(){ 44 } 46 47 57 public static IMethod[] getRelatedMethods(IMethod method, IProgressMonitor pm, WorkingCopyOwner owner) throws JavaModelException { 58 try{ 59 if (! MethodChecks.isVirtual(method) && ! method.getDeclaringType().isInterface()) 60 return new IMethod[]{method}; 61 62 return getAllRippleMethods(method, pm, owner); 63 } finally{ 64 pm.done(); 65 } 66 } 67 68 99 private static IMethod[] getAllRippleMethods(IMethod method, IProgressMonitor pm, WorkingCopyOwner owner) throws JavaModelException { 100 pm.beginTask("", 4); Set result= new HashSet (); 102 Set visitedTypes= new HashSet (); 103 List methodQueue= new ArrayList (); 104 Set hierarchies= new HashSet (); 105 methodQueue.add(method); 106 while (! methodQueue.isEmpty()){ 107 IMethod m= (IMethod)methodQueue.remove(0); 108 109 111 if (m.isBinary()) 112 continue; 113 IType type= m.getDeclaringType(); 114 Assert.isTrue(! visitedTypes.contains(type), "! visitedTypes.contains(type)"); Assert.isTrue(type.isInterface() || declaresAsVirtual(type, method), "second condition"); 117 visitedTypes.add(type); 118 result.add(m); 119 120 IType[] subTypes= getAllSubtypes(pm, owner, type, hierarchies); 121 for (int i= 0; i < subTypes.length; i++){ 122 if (!visitedTypes.contains(subTypes[i])){ 123 IMethod subTypeMethod= Checks.findSimilarMethod(m, subTypes[i]); 124 if (subTypeMethod != null) 125 result.add(subTypeMethod); 126 } 127 } 128 129 for (int i= 0; i < subTypes.length; i++){ 130 IMethod toAdd= findAppropriateMethod(owner, visitedTypes, methodQueue, subTypes[i], method, new NullProgressMonitor()); 131 if (toAdd != null) 132 methodQueue.add(toAdd); 133 } 134 if (pm.isCanceled()) 135 throw new OperationCanceledException(); 136 } 137 return (IMethod[]) result.toArray(new IMethod[result.size()]); 138 } 139 140 private static IType[] getAllSubtypes(IProgressMonitor pm, WorkingCopyOwner owner, IType type, Set cachedHierarchies) throws JavaModelException { 141 for (Iterator iter= cachedHierarchies.iterator(); iter.hasNext();) { 143 ITypeHierarchy hierarchy= (ITypeHierarchy) iter.next(); 144 if (hierarchy.contains(type)) 145 return hierarchy.getAllSubtypes(type); 146 } 147 SubProgressMonitor subPm= new SubProgressMonitor(pm, 1); 148 ITypeHierarchy hierarchy= newTypeHierarchy(type, owner, subPm); 149 cachedHierarchies.add(hierarchy); 150 return hierarchy.getAllSubtypes(type); 151 } 152 153 private static IMethod findAppropriateMethod(WorkingCopyOwner owner, Set visitedTypes, List methodQueue, IType type, IMethod method, IProgressMonitor pm) throws JavaModelException{ 154 pm.beginTask(RefactoringCoreMessages.RippleMethodFinder_analizing_hierarchy, 1); 155 IType[] superTypes= newSupertypeHierarchy(type, owner, new SubProgressMonitor(pm, 1)).getAllSupertypes(type); 156 for (int i= 0; i< superTypes.length; i++){ 157 IType t= superTypes[i]; 158 if (visitedTypes.contains(t)) 159 continue; 160 IMethod found= Checks.findSimilarMethod(method, t); 161 if (found == null) 162 continue; 163 if (! declaresAsVirtual(t, method)) 164 continue; 165 if (methodQueue.contains(found)) 166 continue; 167 return getTopMostMethod(owner, visitedTypes, methodQueue, method, t, new NullProgressMonitor()); 168 } 169 return null; 170 } 171 172 private static IMethod getTopMostMethod(WorkingCopyOwner owner, Set visitedTypes, List methodQueue, IMethod method, IType type, IProgressMonitor pm)throws JavaModelException{ 173 pm.beginTask("", 1); IMethod methodInThisType= Checks.findSimilarMethod(method, type); 175 Assert.isTrue(methodInThisType != null); 176 IType[] superTypes= newSupertypeHierarchy(type, owner, new SubProgressMonitor(pm, 1)).getAllSupertypes(type); 177 for (int i= 0; i < superTypes.length; i++){ 178 IType t= superTypes[i]; 179 if (visitedTypes.contains(t)) 180 continue; 181 IMethod found= Checks.findSimilarMethod(method, t); 182 if (found == null) 183 continue; 184 if (! declaresAsVirtual(t, method)) 185 continue; 186 if (methodQueue.contains(found)) 187 continue; 188 return getTopMostMethod(owner, visitedTypes, methodQueue, method, t, new NullProgressMonitor()); 189 } 190 return methodInThisType; 191 } 192 193 private static boolean declaresAsVirtual(IType type, IMethod m) throws JavaModelException{ 194 IMethod found= Checks.findSimilarMethod(m, type); 195 if (found == null) 196 return false; 197 if (JdtFlags.isStatic(found)) 198 return false; 199 if (JdtFlags.isPrivate(found)) 200 return false; 201 return true; 202 } 203 204 206 private static ITypeHierarchy newTypeHierarchy(IType type, WorkingCopyOwner owner, IProgressMonitor pm) throws JavaModelException { 207 if (owner == null) 208 return type.newTypeHierarchy(pm); 209 else 210 return type.newTypeHierarchy(owner, pm); 211 } 212 213 private static ITypeHierarchy newSupertypeHierarchy(IType type, WorkingCopyOwner owner, IProgressMonitor pm) throws JavaModelException { 214 if (owner == null) 215 return type.newSupertypeHierarchy(pm); 216 else 217 return type.newSupertypeHierarchy(owner, pm); 218 } 219 } 220 | Popular Tags |