1 11 package org.eclipse.jdt.internal.ui.search; 12 13 import java.util.ArrayList ; 14 import java.util.Collection ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 19 import org.eclipse.jface.text.BadLocationException; 20 import org.eclipse.jface.text.IDocument; 21 import org.eclipse.jface.text.IRegion; 22 23 import org.eclipse.search.ui.text.Match; 24 25 import org.eclipse.jdt.core.IJavaElement; 26 import org.eclipse.jdt.core.dom.AST; 27 import org.eclipse.jdt.core.dom.ASTMatcher; 28 import org.eclipse.jdt.core.dom.ASTNode; 29 import org.eclipse.jdt.core.dom.ASTVisitor; 30 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; 31 import org.eclipse.jdt.core.dom.CastExpression; 32 import org.eclipse.jdt.core.dom.CatchClause; 33 import org.eclipse.jdt.core.dom.ClassInstanceCreation; 34 import org.eclipse.jdt.core.dom.CompilationUnit; 35 import org.eclipse.jdt.core.dom.ConstructorInvocation; 36 import org.eclipse.jdt.core.dom.IMethodBinding; 37 import org.eclipse.jdt.core.dom.ITypeBinding; 38 import org.eclipse.jdt.core.dom.IVariableBinding; 39 import org.eclipse.jdt.core.dom.Javadoc; 40 import org.eclipse.jdt.core.dom.MethodDeclaration; 41 import org.eclipse.jdt.core.dom.MethodInvocation; 42 import org.eclipse.jdt.core.dom.Name; 43 import org.eclipse.jdt.core.dom.SimpleName; 44 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 45 import org.eclipse.jdt.core.dom.SuperConstructorInvocation; 46 import org.eclipse.jdt.core.dom.SuperMethodInvocation; 47 import org.eclipse.jdt.core.dom.ThrowStatement; 48 import org.eclipse.jdt.core.dom.TryStatement; 49 import org.eclipse.jdt.core.dom.Type; 50 import org.eclipse.jdt.core.dom.TypeDeclarationStatement; 51 52 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 53 import org.eclipse.jdt.internal.corext.dom.Bindings; 54 import org.eclipse.jdt.internal.corext.dom.NodeFinder; 55 56 public class ExceptionOccurrencesFinder extends ASTVisitor implements IOccurrencesFinder { 57 58 public static final String IS_EXCEPTION= "isException"; 60 private AST fAST; 61 private Name fSelectedName; 62 63 private ITypeBinding fException; 64 private ASTNode fStart; 65 private List fResult; 66 67 public ExceptionOccurrencesFinder() { 68 fResult= new ArrayList (); 69 } 70 71 public String initialize(CompilationUnit root, int offset, int length) { 72 return initialize(root, NodeFinder.perform(root, offset, length)); 73 } 74 75 public String initialize(CompilationUnit root, ASTNode node) { 76 fAST= root.getAST(); 77 if (!(node instanceof Name)) { 78 return SearchMessages.ExceptionOccurrencesFinder_no_exception; 79 } 80 fSelectedName= ASTNodes.getTopMostName((Name)node); 81 ASTNode parent= fSelectedName.getParent(); 82 MethodDeclaration decl= resolveMethodDeclaration(parent); 83 if (decl != null && methodThrowsException(decl, fSelectedName)) { 84 fException= fSelectedName.resolveTypeBinding(); 85 fStart= decl.getBody(); 86 } else if (parent instanceof Type) { 87 parent= parent.getParent(); 88 if (parent instanceof SingleVariableDeclaration && parent.getParent() instanceof CatchClause) { 89 CatchClause catchClause= (CatchClause)parent.getParent(); 90 TryStatement tryStatement= (TryStatement)catchClause.getParent(); 91 if (tryStatement != null) { 92 IVariableBinding var= catchClause.getException().resolveBinding(); 93 if (var != null && var.getType() != null) { 94 fException= var.getType(); 95 fStart= tryStatement.getBody(); 96 } 97 } 98 } 99 } 100 if (fException == null || fStart == null) 101 return SearchMessages.ExceptionOccurrencesFinder_no_exception; 102 return null; 103 } 104 105 private MethodDeclaration resolveMethodDeclaration(ASTNode node) { 106 if (node instanceof MethodDeclaration) 107 return (MethodDeclaration)node; 108 Javadoc doc= (Javadoc) ASTNodes.getParent(node, ASTNode.JAVADOC); 109 if (doc == null) 110 return null; 111 if (doc.getParent() instanceof MethodDeclaration) 112 return (MethodDeclaration) doc.getParent(); 113 return null; 114 } 115 116 private boolean methodThrowsException(MethodDeclaration method, Name exception) { 117 ASTMatcher matcher = new ASTMatcher(); 118 for (Iterator iter = method.thrownExceptions().iterator(); iter.hasNext();) { 119 Name thrown = (Name)iter.next(); 120 if (exception.subtreeMatch(matcher, thrown)) 121 return true; 122 } 123 return false; 124 } 125 126 public List perform() { 127 fStart.accept(this); 128 if (fSelectedName != null) { 129 fResult.add(fSelectedName); 130 } 131 return fResult; 132 } 133 134 public void collectOccurrenceMatches(IJavaElement element, IDocument document, Collection resultingMatches) { 135 HashMap lineToLineElement= new HashMap (); 136 137 for (Iterator iter= fResult.iterator(); iter.hasNext();) { 138 ASTNode node= (ASTNode) iter.next(); 139 int startPosition= node.getStartPosition(); 140 int length= node.getLength(); 141 try { 142 boolean isException= node == fSelectedName; 143 int line= document.getLineOfOffset(startPosition); 144 Integer lineInteger= new Integer (line); 145 ExceptionOccurrencesGroupKey groupKey= (ExceptionOccurrencesGroupKey) lineToLineElement.get(lineInteger); 146 if (groupKey == null) { 147 IRegion region= document.getLineInformation(line); 148 String lineContents= document.get(region.getOffset(), region.getLength()).trim(); 149 groupKey= new ExceptionOccurrencesGroupKey(element, line, lineContents, isException); 150 lineToLineElement.put(lineInteger, groupKey); 151 } else if (isException) { 152 groupKey.setException(true); 154 } 155 Match match= new Match(groupKey, startPosition, length); 156 resultingMatches.add(match); 157 } catch (BadLocationException e) { 158 } 160 } 161 } 162 163 public String getJobLabel() { 164 return SearchMessages.ExceptionOccurrencesFinder_searchfor ; 165 } 166 167 public String getElementName() { 168 if (fSelectedName != null) { 169 return ASTNodes.asString(fSelectedName); 170 } 171 return null; 172 } 173 174 public String getUnformattedPluralLabel() { 175 return SearchMessages.ExceptionOccurrencesFinder_label_plural; 176 } 177 178 public String getUnformattedSingularLabel() { 179 return SearchMessages.ExceptionOccurrencesFinder_label_singular; 180 } 181 182 public boolean visit(AnonymousClassDeclaration node) { 183 return false; 184 } 185 186 public boolean visit(CastExpression node) { 187 if ("java.lang.ClassCastException".equals(fException.getQualifiedName())) fResult.add(node.getType()); 189 return super.visit(node); 190 } 191 192 public boolean visit(ClassInstanceCreation node) { 193 if (matches(node.resolveConstructorBinding())) { 194 fResult.add(node.getType()); 195 } 196 return super.visit(node); 197 } 198 199 public boolean visit(ConstructorInvocation node) { 200 if (matches(node.resolveConstructorBinding())) { 201 SimpleName name= fAST.newSimpleName("xxxx"); name.setSourceRange(node.getStartPosition(), 4); 204 fResult.add(name); 205 } 206 return super.visit(node); 207 } 208 209 public boolean visit(MethodInvocation node) { 210 if (matches(node.resolveMethodBinding())) 211 fResult.add(node.getName()); 212 return super.visit(node); 213 } 214 215 public boolean visit(SuperConstructorInvocation node) { 216 if (matches(node.resolveConstructorBinding())) { 217 SimpleName name= fAST.newSimpleName("xxxxx"); name.setSourceRange(node.getStartPosition(), 5); 219 fResult.add(name); 220 } 221 return super.visit(node); 222 } 223 224 public boolean visit(SuperMethodInvocation node) { 225 if (matches(node.resolveMethodBinding())) { 226 fResult.add(node.getName()); 227 } 228 return super.visit(node); 229 } 230 231 public boolean visit(ThrowStatement node) { 232 if (matches(node.getExpression().resolveTypeBinding())) { 233 SimpleName name= fAST.newSimpleName("xxxxx"); name.setSourceRange(node.getStartPosition(), 5); 235 fResult.add(name); 236 237 } 238 return super.visit(node); 239 } 240 241 public boolean visit(TypeDeclarationStatement node) { 242 return false; 244 } 245 246 private boolean matches(IMethodBinding binding) { 247 if (binding == null) 248 return false; 249 ITypeBinding[] exceptions= binding.getExceptionTypes(); 250 for (int i = 0; i < exceptions.length; i++) { 251 ITypeBinding exception= exceptions[i]; 252 if(matches(exception)) 253 return true; 254 } 255 return false; 256 } 257 258 private boolean matches(ITypeBinding exception) { 259 if (exception == null) 260 return false; 261 while (exception != null) { 262 if (Bindings.equals(fException, exception)) 263 return true; 264 exception= exception.getSuperclass(); 265 } 266 return false; 267 } 268 269 270 } 271 | Popular Tags |