1 11 package org.eclipse.jdt.apt.core.internal.util; 12 13 import java.util.ArrayList ; 14 import java.util.Arrays ; 15 import java.util.List ; 16 import java.util.Map ; 17 18 import org.eclipse.jdt.core.dom.ASTNode; 19 import org.eclipse.jdt.core.dom.ASTVisitor; 20 import org.eclipse.jdt.core.dom.Annotation; 21 import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; 22 import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration; 23 import org.eclipse.jdt.core.dom.Block; 24 import org.eclipse.jdt.core.dom.BodyDeclaration; 25 import org.eclipse.jdt.core.dom.DoStatement; 26 import org.eclipse.jdt.core.dom.EnumConstantDeclaration; 27 import org.eclipse.jdt.core.dom.EnumDeclaration; 28 import org.eclipse.jdt.core.dom.FieldDeclaration; 29 import org.eclipse.jdt.core.dom.ForStatement; 30 import org.eclipse.jdt.core.dom.IExtendedModifier; 31 import org.eclipse.jdt.core.dom.IfStatement; 32 import org.eclipse.jdt.core.dom.MarkerAnnotation; 33 import org.eclipse.jdt.core.dom.MethodDeclaration; 34 import org.eclipse.jdt.core.dom.NormalAnnotation; 35 import org.eclipse.jdt.core.dom.SingleMemberAnnotation; 36 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 37 import org.eclipse.jdt.core.dom.TryStatement; 38 import org.eclipse.jdt.core.dom.TypeDeclaration; 39 40 43 @SuppressWarnings ("unchecked") public class Visitors { 45 46 51 public static final class AnnotationVisitor extends ASTVisitor 52 { 53 private final List <Annotation> _annotations; 54 57 public AnnotationVisitor(final List <Annotation> annotations) 58 { _annotations = annotations; } 59 60 public boolean visit(MarkerAnnotation annotation) 61 { 62 _annotations.add(annotation); 63 return false; 64 } 65 66 public boolean visit(SingleMemberAnnotation annotation) 67 { 68 _annotations.add(annotation); 69 return false; 70 } 71 72 public boolean visit(NormalAnnotation annotation) 73 { 74 _annotations.add(annotation); 75 return false; 76 } 77 78 public boolean visit(Block blk){ return false; } 80 public boolean visit(DoStatement doStatement){ return false; } 81 public boolean visit(ForStatement forStatement){ return false; } 82 public boolean visit(IfStatement ifStatement){ return false; } 83 public boolean visit(TryStatement tryStatement){ return false; } 84 85 public void reset(){ _annotations.clear(); } 86 } 87 88 93 public static final class AnnotatedNodeVisitor extends ASTVisitor 94 { 95 private final Map <ASTNode, List <Annotation>> _result; 96 97 102 public AnnotatedNodeVisitor(Map <ASTNode, List <Annotation>> map) 103 { 104 _result = map; 105 } 106 107 110 public boolean visit(org.eclipse.jdt.core.dom.PackageDeclaration node) 111 { 112 final List <Annotation> annotations = node.annotations(); 113 if( !annotations.isEmpty() ) 114 _result.put(node, annotations); 115 116 return false; 117 } 118 119 122 public boolean visit(org.eclipse.jdt.core.dom.TypeDeclaration node) 123 { 124 visitBodyDeclaration(node); 125 return true; 126 } 127 128 131 public boolean visit(org.eclipse.jdt.core.dom.AnnotationTypeDeclaration node) 132 { 133 visitBodyDeclaration(node); 134 return true; 135 } 136 137 140 public boolean visit(org.eclipse.jdt.core.dom.EnumDeclaration node) 141 { 142 visitBodyDeclaration(node); 143 return true; 144 } 145 146 149 public boolean visit(org.eclipse.jdt.core.dom.FieldDeclaration node) 150 { 151 visitBodyDeclaration(node); 152 return true; 153 } 154 155 158 public boolean visit(org.eclipse.jdt.core.dom.EnumConstantDeclaration node) 159 { 160 visitBodyDeclaration(node); 161 return true; 162 } 163 164 167 public boolean visit(MethodDeclaration node) 168 { 169 visitBodyDeclaration(node); 170 return true; 171 } 172 173 176 public boolean visit(AnnotationTypeMemberDeclaration node) 177 { 178 visitBodyDeclaration(node); 179 return true; 180 } 181 182 private void visitBodyDeclaration(final BodyDeclaration node) 183 { 184 final List <IExtendedModifier> extMods = node.modifiers(); 185 List <Annotation> annos = null; 186 for( IExtendedModifier extMod : extMods ){ 187 if( extMod.isAnnotation() ){ 188 if( annos == null ){ 189 annos = new ArrayList <Annotation>(2); 190 _result.put(node, annos); 191 } 192 annos.add((Annotation)extMod); 193 } 194 } 195 } 196 197 200 public boolean visit(SingleVariableDeclaration node) 201 { 202 final List <IExtendedModifier> extMods = node.modifiers(); 203 List <Annotation> annos = null; 204 for( IExtendedModifier extMod : extMods ){ 205 if( extMod.isAnnotation() ){ 206 if( annos == null ){ 207 annos = new ArrayList <Annotation>(2); 208 _result.put(node, annos); 209 } 210 annos.add((Annotation)extMod); 211 } 212 } 213 return false; 214 } 215 216 219 public boolean visit(Block node) 220 { return false; 222 } 223 public boolean visit(MarkerAnnotation node){ return false; } 224 public boolean visit(NormalAnnotation node){ return false; } 225 public boolean visit(SingleMemberAnnotation node){ return false; } 226 } 227 228 234 public static final class DeclarationFinder extends ASTVisitor 235 { 236 private final Annotation _anno; 237 private ASTNode _result = null; 241 public DeclarationFinder(final Annotation annotation) 242 { 243 _anno = annotation; 244 } 245 246 249 public ASTNode getAnnotatedNode(){return _result;} 250 251 254 public boolean visit(AnnotationTypeDeclaration node) { 255 return internalVisit(node); 256 } 257 258 public boolean visit(AnnotationTypeMemberDeclaration node) { 259 return internalVisit(node); 260 } 261 262 public boolean visit(EnumDeclaration node) { 263 return internalVisit(node); 264 } 265 266 public boolean visit(EnumConstantDeclaration node) { 267 return internalVisit(node); 268 } 269 270 public boolean visit(FieldDeclaration node) { 271 return internalVisit(node); 272 } 273 274 public boolean visit(MethodDeclaration node) { 275 return internalVisit(node); 276 } 277 278 public boolean visit(TypeDeclaration node) { 279 return internalVisit(node); 280 } 281 282 public boolean visit(SingleVariableDeclaration node) { 283 return internalVisit(node); 284 } 285 286 private boolean internalVisit(ASTNode node) { 287 if( _result != null ) return false; 289 int nodeStart = node.getStartPosition(); 290 int nodeEnd = nodeStart + node.getLength(); 291 int annoStart = _anno.getStartPosition(); 292 int annoEnd = annoStart + _anno.getLength(); 293 294 if (nodeStart > annoEnd) { 295 return false; 297 } 298 if (nodeEnd > annoStart) { List <IExtendedModifier> extendedModifiers; 301 if (node.getNodeType() == ASTNode.SINGLE_VARIABLE_DECLARATION) { 302 SingleVariableDeclaration declaration = (SingleVariableDeclaration)node; 303 extendedModifiers = declaration.modifiers(); 304 } 305 else { 306 BodyDeclaration declaration = (BodyDeclaration)node; 307 extendedModifiers = declaration.modifiers(); 308 } 309 for (IExtendedModifier modifier : extendedModifiers) { 310 if( modifier == _anno ){ 312 _result = node; 313 return false; 314 } 315 } 316 } 317 318 return true; 320 } 321 322 325 public boolean visit(Block node) 326 { return false; 328 } 329 public boolean visit(MarkerAnnotation node){ return false; } 330 public boolean visit(NormalAnnotation node){ return false; } 331 public boolean visit(SingleMemberAnnotation node){ return false; } 332 } 333 338 public static class EndingOffsetFinder extends ASTVisitor 339 { 340 private final int[] _sortedStartingOffset; 341 346 private final int[] _endingOffsets; 347 348 352 public EndingOffsetFinder(int[] offsets) 353 { 354 if(offsets == null) 355 throw new IllegalArgumentException ("argument cannot be null."); Arrays.sort(offsets); 358 359 int count = 0; 361 for( int i=1, len=offsets.length; i<len; i++){ 362 if( offsets[i-1] == offsets[i] ) 363 continue; 364 count ++; 365 } 366 367 if( count != offsets.length ){ 368 _sortedStartingOffset = new int[count]; 369 370 int index = 0; 371 for( int i=0, len=offsets.length; i<len; i++){ 372 if( i != 0 && offsets[i-1] == offsets[i] ) 373 continue; 374 _sortedStartingOffset[index++] = offsets[i]; 375 } 376 } 377 else{ 378 _sortedStartingOffset = offsets; 379 } 380 381 _endingOffsets = new int[count]; 382 for( int i=0; i<count; i++ ) 383 _endingOffsets[i] = 0; 384 } 385 386 public void preVisit(ASTNode node) 387 { 388 final int startingOffset = node.getStartPosition(); 389 final int endingOffset = startingOffset + node.getLength(); 390 int startIndex = Arrays.binarySearch(_sortedStartingOffset, startingOffset); 392 int endIndex = Arrays.binarySearch(_sortedStartingOffset, endingOffset); 394 if( startIndex < 0 ) 395 startIndex = - startIndex - 1; 396 if( endIndex < 0 ) 397 endIndex = - endIndex - 1; 398 else 399 endIndex ++; 402 if( startIndex >= _sortedStartingOffset.length ) 403 return; 404 405 for( int i=startIndex; i<endIndex; i++ ){ 406 if( _endingOffsets[i] == 0 ) 407 _endingOffsets[i] = endingOffset; 408 else if( endingOffset < _endingOffsets[i] ) 409 _endingOffsets[i] = endingOffset; 410 } 411 } 412 413 414 public int getEndingOffset(final int startingOffset) 415 { 416 int index = Arrays.binarySearch(_sortedStartingOffset, startingOffset); 417 if( index == -1 ) return 0; 418 return _endingOffsets[index]; 419 } 420 } 421 } 422 | Popular Tags |