1 11 package org.eclipse.jdt.internal.corext.refactoring.structure; 12 13 import java.util.ArrayList ; 14 import java.util.Collection ; 15 import java.util.HashMap ; 16 import java.util.HashSet ; 17 import java.util.Iterator ; 18 import java.util.List ; 19 import java.util.Set ; 20 21 import org.eclipse.jdt.core.IJavaProject; 22 import org.eclipse.jdt.core.dom.ASTNode; 23 import org.eclipse.jdt.core.dom.ASTVisitor; 24 import org.eclipse.jdt.core.dom.CompilationUnit; 25 import org.eclipse.jdt.core.dom.IBinding; 26 import org.eclipse.jdt.core.dom.IMethodBinding; 27 import org.eclipse.jdt.core.dom.ITypeBinding; 28 import org.eclipse.jdt.core.dom.IVariableBinding; 29 import org.eclipse.jdt.core.dom.QualifiedName; 30 import org.eclipse.jdt.core.dom.QualifiedType; 31 import org.eclipse.jdt.core.dom.SimpleName; 32 import org.eclipse.jdt.core.dom.Type; 33 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; 34 35 import org.eclipse.jdt.internal.corext.codemanipulation.ImportReferencesCollector; 36 import org.eclipse.jdt.internal.corext.dom.Bindings; 37 38 public class ImportRemover { 39 40 private static class StaticImportData { 41 42 private boolean fField; 43 44 private String fMember; 45 46 private String fQualifier; 47 48 private StaticImportData(String qualifier, String member, boolean field) { 49 fQualifier= qualifier; 50 fMember= member; 51 fField= field; 52 } 53 } 54 55 private Set fAddedImports= new HashSet (); 56 57 private Set fAddedStaticImports= new HashSet (); 58 59 private final IJavaProject fProject; 60 61 private List fRemovedNodes= new ArrayList (); 62 63 private final CompilationUnit fRoot; 64 65 public ImportRemover(IJavaProject project, CompilationUnit root) { 66 fProject= project; 67 fRoot= root; 68 } 69 70 private void divideTypeRefs(List importNames, List staticNames, List removedRefs, List unremovedRefs) { 71 int[] removedStartsEnds= new int[2 * fRemovedNodes.size()]; 72 for (int index= 0; index < fRemovedNodes.size(); index++) { 73 ASTNode node= (ASTNode) fRemovedNodes.get(index); 74 int start= node.getStartPosition(); 75 removedStartsEnds[2 * index]= start; 76 removedStartsEnds[2 * index + 1]= start + node.getLength(); 77 } 78 for (Iterator iterator= importNames.iterator(); iterator.hasNext();) { 79 SimpleName name= (SimpleName) iterator.next(); 80 if (isInRemoved(name, removedStartsEnds)) 81 removedRefs.add(name); 82 else 83 unremovedRefs.add(name); 84 } 85 for (Iterator iterator= staticNames.iterator(); iterator.hasNext();) { 86 SimpleName name= (SimpleName) iterator.next(); 87 if (isInRemoved(name, removedStartsEnds)) 88 removedRefs.add(name); 89 else 90 unremovedRefs.add(name); 91 } 92 } 93 94 public IBinding[] getImportsToRemove() { 95 ArrayList importNames= new ArrayList (); 96 ArrayList staticNames= new ArrayList (); 97 fRoot.accept(new ImportReferencesCollector(fProject, null, importNames, staticNames)); 98 List removedRefs= new ArrayList (); 99 List unremovedRefs= new ArrayList (); 100 divideTypeRefs(importNames, staticNames, removedRefs, unremovedRefs); 101 if (removedRefs.size() == 0) 102 return new IBinding[0]; 103 104 HashMap potentialRemoves= getPotentialRemoves(removedRefs); 105 for (Iterator iterator= unremovedRefs.iterator(); iterator.hasNext();) { 106 SimpleName name= (SimpleName) iterator.next(); 107 potentialRemoves.remove(name.getIdentifier()); 108 } 109 110 Collection importsToRemove= potentialRemoves.values(); 111 return (IBinding[]) importsToRemove.toArray(new IBinding[importsToRemove.size()]); 112 } 113 114 private HashMap getPotentialRemoves(List removedRefs) { 115 HashMap potentialRemoves= new HashMap (); 116 for (Iterator iterator= removedRefs.iterator(); iterator.hasNext();) { 117 SimpleName name= (SimpleName) iterator.next(); 118 if (fAddedImports.contains(name.getIdentifier()) || hasAddedStaticImport(name)) 119 continue; 120 IBinding binding= name.resolveBinding(); 121 if (binding != null) 122 potentialRemoves.put(name.getIdentifier(), binding); 123 } 124 return potentialRemoves; 125 } 126 127 private boolean hasAddedStaticImport(SimpleName name) { 128 IBinding binding= name.resolveBinding(); 129 if (binding instanceof IVariableBinding) { 130 IVariableBinding variable= (IVariableBinding) binding; 131 return hasAddedStaticImport(variable.getDeclaringClass().getQualifiedName(), variable.getName(), true); 132 } else if (binding instanceof IMethodBinding) { 133 IMethodBinding method= (IMethodBinding) binding; 134 return hasAddedStaticImport(method.getDeclaringClass().getQualifiedName(), method.getName(), false); 135 } 136 return false; 137 } 138 139 private boolean hasAddedStaticImport(String qualifier, String member, boolean field) { 140 StaticImportData data= null; 141 for (final Iterator iterator= fAddedStaticImports.iterator(); iterator.hasNext();) { 142 data= (StaticImportData) iterator.next(); 143 if (data.fQualifier.equals(qualifier) && data.fMember.equals(member) && data.fField == field) 144 return true; 145 } 146 return false; 147 } 148 149 public boolean hasRemovedNodes() { 150 return fRemovedNodes.size() != 0; 151 } 152 153 private boolean isInRemoved(SimpleName ref, int[] removedStartsEnds) { 154 int start= ref.getStartPosition(); 155 int end= start + ref.getLength(); 156 for (int index= 0; index < removedStartsEnds.length; index+= 2) { 157 if (start >= removedStartsEnds[index] && end <= removedStartsEnds[index + 1]) 158 return true; 159 } 160 return false; 161 } 162 163 public void registerAddedImport(String typeName) { 164 int dot= typeName.lastIndexOf('.'); 165 if (dot == -1) 166 fAddedImports.add(typeName); 167 else 168 fAddedImports.add(typeName.substring(dot + 1)); 169 } 170 171 public void registerAddedImports(Type newTypeNode) { 172 newTypeNode.accept(new ASTVisitor(true) { 173 174 private void addName(SimpleName name) { 175 fAddedImports.add(name.getIdentifier()); 176 } 177 178 public boolean visit(QualifiedName node) { 179 addName(node.getName()); 180 return false; 181 } 182 183 public boolean visit(QualifiedType node) { 184 addName(node.getName()); 185 return false; 186 } 187 188 public boolean visit(SimpleName node) { 189 addName(node); 190 return false; 191 } 192 }); 193 } 194 195 public void registerAddedStaticImport(String qualifier, String member, boolean field) { 196 fAddedStaticImports.add(new StaticImportData(qualifier, member, field)); 197 } 198 199 public void registerAddedStaticImport(IBinding binding) { 200 if (binding instanceof IVariableBinding) { 201 ITypeBinding declaringType= ((IVariableBinding) binding).getDeclaringClass(); 202 fAddedStaticImports.add(new StaticImportData(Bindings.getRawQualifiedName(declaringType), binding.getName(), true)); 203 204 } else if (binding instanceof IMethodBinding) { 205 ITypeBinding declaringType= ((IMethodBinding) binding).getDeclaringClass(); 206 fAddedStaticImports.add(new StaticImportData(Bindings.getRawQualifiedName(declaringType), binding.getName(), false)); 207 208 } else { 209 throw new IllegalArgumentException (binding.toString()); 210 } 211 } 212 213 public void registerRemovedNode(ASTNode removed) { 214 fRemovedNodes.add(removed); 215 } 216 217 218 public void applyRemoves(ImportRewrite importRewrite) { 219 IBinding[] bindings= getImportsToRemove(); 220 for (int i= 0; i < bindings.length; i++) { 221 if (bindings[i] instanceof ITypeBinding) { 222 ITypeBinding typeBinding= (ITypeBinding) bindings[i]; 223 importRewrite.removeImport(typeBinding.getTypeDeclaration().getQualifiedName()); 224 } else if (bindings[i] instanceof IMethodBinding) { 225 IMethodBinding binding= (IMethodBinding) bindings[i]; 226 importRewrite.removeStaticImport(binding.getDeclaringClass().getQualifiedName() + '.' + binding.getName()); 227 } else if (bindings[i] instanceof IVariableBinding) { 228 IVariableBinding binding= (IVariableBinding) bindings[i]; 229 importRewrite.removeStaticImport(binding.getDeclaringClass().getQualifiedName() + '.' + binding.getName()); 230 } 231 } 232 } 233 } 234 | Popular Tags |