1 11 package org.eclipse.jdt.internal.core; 12 13 import java.util.ArrayList ; 14 import java.util.HashMap ; 15 import java.util.Map ; 16 import java.util.Stack ; 17 18 import org.eclipse.core.runtime.Assert; 19 import org.eclipse.jdt.core.*; 20 import org.eclipse.jdt.core.compiler.CategorizedProblem; 21 import org.eclipse.jdt.core.compiler.CharOperation; 22 import org.eclipse.jdt.core.compiler.IProblem; 23 import org.eclipse.jdt.internal.compiler.ISourceElementRequestor; 24 import org.eclipse.jdt.internal.compiler.parser.Parser; 25 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; 26 import org.eclipse.jdt.internal.core.util.ReferenceInfoAdapter; 27 28 31 public class CompilationUnitStructureRequestor extends ReferenceInfoAdapter implements ISourceElementRequestor { 32 33 36 protected ICompilationUnit unit; 37 38 41 protected CompilationUnitElementInfo unitInfo; 42 43 46 protected JavaElementInfo importContainerInfo = null; 47 48 54 protected Map newElements; 55 56 62 protected Stack infoStack; 63 64 68 protected HashMap children; 69 70 75 protected Stack handleStack; 76 77 81 protected int referenceCount= 0; 82 83 86 protected boolean hasSyntaxErrors = false; 87 88 91 protected Parser parser; 92 93 96 protected static byte[] NO_BYTES= new byte[]{}; 97 98 protected HashtableOfObject fieldRefCache; 99 protected HashtableOfObject messageRefCache; 100 protected HashtableOfObject typeRefCache; 101 protected HashtableOfObject unknownRefCache; 102 103 protected CompilationUnitStructureRequestor(ICompilationUnit unit, CompilationUnitElementInfo unitInfo, Map newElements) { 104 this.unit = unit; 105 this.unitInfo = unitInfo; 106 this.newElements = newElements; 107 } 108 111 public void acceptImport(int declarationStart, int declarationEnd, char[][] tokens, boolean onDemand, int modifiers) { 112 JavaElement parentHandle= (JavaElement) this.handleStack.peek(); 113 if (!(parentHandle.getElementType() == IJavaElement.COMPILATION_UNIT)) { 114 Assert.isTrue(false); } 116 117 ICompilationUnit parentCU= (ICompilationUnit)parentHandle; 118 ImportContainer importContainer= (ImportContainer)parentCU.getImportContainer(); 120 if (this.importContainerInfo == null) { 121 this.importContainerInfo = new JavaElementInfo(); 122 JavaElementInfo parentInfo = (JavaElementInfo) this.infoStack.peek(); 123 addToChildren(parentInfo, importContainer); 124 this.newElements.put(importContainer, this.importContainerInfo); 125 } 126 127 String elementName = JavaModelManager.getJavaModelManager().intern(new String (CharOperation.concatWith(tokens, '.'))); 128 ImportDeclaration handle = new ImportDeclaration(importContainer, elementName, onDemand); 129 resolveDuplicates(handle); 130 131 ImportDeclarationElementInfo info = new ImportDeclarationElementInfo(); 132 info.setSourceRangeStart(declarationStart); 133 info.setSourceRangeEnd(declarationEnd); 134 info.setFlags(modifiers); 135 136 addToChildren(this.importContainerInfo, handle); 137 this.newElements.put(handle, info); 138 } 139 146 public void acceptLineSeparatorPositions(int[] positions) { 147 } 149 152 public void acceptPackage(int declarationStart, int declarationEnd, char[] name) { 153 154 JavaElementInfo parentInfo = (JavaElementInfo) this.infoStack.peek(); 155 JavaElement parentHandle= (JavaElement) this.handleStack.peek(); 156 PackageDeclaration handle = null; 157 158 if (parentHandle.getElementType() == IJavaElement.COMPILATION_UNIT) { 159 handle = new PackageDeclaration((CompilationUnit) parentHandle, new String (name)); 160 } 161 else { 162 Assert.isTrue(false); } 164 resolveDuplicates(handle); 165 166 SourceRefElementInfo info = new SourceRefElementInfo(); 167 info.setSourceRangeStart(declarationStart); 168 info.setSourceRangeEnd(declarationEnd); 169 170 addToChildren(parentInfo, handle); 171 this.newElements.put(handle, info); 172 173 } 174 public void acceptProblem(CategorizedProblem problem) { 175 if ((problem.getID() & IProblem.Syntax) != 0){ 176 this.hasSyntaxErrors = true; 177 } 178 } 179 private void addToChildren(JavaElementInfo parentInfo, JavaElement handle) { 180 ArrayList childrenList = (ArrayList ) this.children.get(parentInfo); 181 if (childrenList == null) 182 this.children.put(parentInfo, childrenList = new ArrayList ()); 183 childrenList.add(handle); 184 } 185 189 static String [] convertTypeNamesToSigs(char[][] typeNames) { 190 if (typeNames == null) 191 return CharOperation.NO_STRINGS; 192 int n = typeNames.length; 193 if (n == 0) 194 return CharOperation.NO_STRINGS; 195 JavaModelManager manager = JavaModelManager.getJavaModelManager(); 196 String [] typeSigs = new String [n]; 197 for (int i = 0; i < n; ++i) { 198 typeSigs[i] = manager.intern(Signature.createTypeSignature(typeNames[i], false)); 199 } 200 return typeSigs; 201 } 202 205 public void enterCompilationUnit() { 206 this.infoStack = new Stack (); 207 this.children = new HashMap (); 208 this.handleStack= new Stack (); 209 this.infoStack.push(this.unitInfo); 210 this.handleStack.push(this.unit); 211 } 212 215 public void enterConstructor(MethodInfo methodInfo) { 216 enterMethod(methodInfo); 217 } 218 221 public void enterField(FieldInfo fieldInfo) { 222 223 SourceTypeElementInfo parentInfo = (SourceTypeElementInfo) this.infoStack.peek(); 224 JavaElement parentHandle= (JavaElement) this.handleStack.peek(); 225 SourceField handle = null; 226 if (parentHandle.getElementType() == IJavaElement.TYPE) { 227 String fieldName = JavaModelManager.getJavaModelManager().intern(new String (fieldInfo.name)); 228 handle = new SourceField(parentHandle, fieldName); 229 } 230 else { 231 Assert.isTrue(false); } 233 resolveDuplicates(handle); 234 235 SourceFieldElementInfo info = new SourceFieldElementInfo(); 236 info.setNameSourceStart(fieldInfo.nameSourceStart); 237 info.setNameSourceEnd(fieldInfo.nameSourceEnd); 238 info.setSourceRangeStart(fieldInfo.declarationStart); 239 info.setFlags(fieldInfo.modifiers); 240 char[] typeName = JavaModelManager.getJavaModelManager().intern(fieldInfo.type); 241 info.setTypeName(typeName); 242 243 this.unitInfo.addAnnotationPositions(handle, fieldInfo.annotationPositions); 244 245 addToChildren(parentInfo, handle); 246 parentInfo.addCategories(handle, fieldInfo.categories); 247 this.newElements.put(handle, info); 248 249 this.infoStack.push(info); 250 this.handleStack.push(handle); 251 } 252 255 public void enterInitializer( 256 int declarationSourceStart, 257 int modifiers) { 258 JavaElementInfo parentInfo = (JavaElementInfo) this.infoStack.peek(); 259 JavaElement parentHandle= (JavaElement) this.handleStack.peek(); 260 Initializer handle = null; 261 262 if (parentHandle.getElementType() == IJavaElement.TYPE) { 263 handle = new Initializer(parentHandle, 1); 264 } 265 else { 266 Assert.isTrue(false); } 268 resolveDuplicates(handle); 269 270 InitializerElementInfo info = new InitializerElementInfo(); 271 info.setSourceRangeStart(declarationSourceStart); 272 info.setFlags(modifiers); 273 274 addToChildren(parentInfo, handle); 275 this.newElements.put(handle, info); 276 277 this.infoStack.push(info); 278 this.handleStack.push(handle); 279 } 280 283 public void enterMethod(MethodInfo methodInfo) { 284 285 SourceTypeElementInfo parentInfo = (SourceTypeElementInfo) this.infoStack.peek(); 286 JavaElement parentHandle= (JavaElement) this.handleStack.peek(); 287 SourceMethod handle = null; 288 289 if (methodInfo.parameterTypes == null) { 291 methodInfo.parameterTypes= CharOperation.NO_CHAR_CHAR; 292 } 293 if (methodInfo.parameterNames == null) { 294 methodInfo.parameterNames= CharOperation.NO_CHAR_CHAR; 295 } 296 if (methodInfo.exceptionTypes == null) { 297 methodInfo.exceptionTypes= CharOperation.NO_CHAR_CHAR; 298 } 299 300 String [] parameterTypeSigs = convertTypeNamesToSigs(methodInfo.parameterTypes); 301 if (parentHandle.getElementType() == IJavaElement.TYPE) { 302 String selector = JavaModelManager.getJavaModelManager().intern(new String (methodInfo.name)); 303 handle = new SourceMethod(parentHandle, selector, parameterTypeSigs); 304 } 305 else { 306 Assert.isTrue(false); } 308 resolveDuplicates(handle); 309 310 SourceMethodElementInfo info; 311 if (methodInfo.isConstructor) 312 info = new SourceConstructorInfo(); 313 else if (methodInfo.isAnnotation) 314 info = new SourceAnnotationMethodInfo(); 315 else 316 info = new SourceMethodInfo(); 317 info.setSourceRangeStart(methodInfo.declarationStart); 318 int flags = methodInfo.modifiers; 319 info.setNameSourceStart(methodInfo.nameSourceStart); 320 info.setNameSourceEnd(methodInfo.nameSourceEnd); 321 info.setFlags(flags); 322 JavaModelManager manager = JavaModelManager.getJavaModelManager(); 323 char[][] parameterNames = methodInfo.parameterNames; 324 for (int i = 0, length = parameterNames.length; i < length; i++) 325 parameterNames[i] = manager.intern(parameterNames[i]); 326 info.setArgumentNames(parameterNames); 327 char[] returnType = methodInfo.returnType == null ? new char[]{'v', 'o','i', 'd'} : methodInfo.returnType; 328 info.setReturnType(manager.intern(returnType)); 329 char[][] exceptionTypes = methodInfo.exceptionTypes; 330 info.setExceptionTypeNames(exceptionTypes); 331 for (int i = 0, length = exceptionTypes.length; i < length; i++) 332 exceptionTypes[i] = manager.intern(exceptionTypes[i]); 333 this.unitInfo.addAnnotationPositions(handle, methodInfo.annotationPositions); 334 addToChildren(parentInfo, handle); 335 parentInfo.addCategories(handle, methodInfo.categories); 336 this.newElements.put(handle, info); 337 this.infoStack.push(info); 338 this.handleStack.push(handle); 339 340 if (methodInfo.typeParameters != null) { 341 for (int i = 0, length = methodInfo.typeParameters.length; i < length; i++) { 342 TypeParameterInfo typeParameterInfo = methodInfo.typeParameters[i]; 343 enterTypeParameter(typeParameterInfo); 344 exitMember(typeParameterInfo.declarationEnd); 345 } 346 } 347 } 348 351 public void enterType(TypeInfo typeInfo) { 352 353 JavaElementInfo parentInfo = (JavaElementInfo) this.infoStack.peek(); 354 JavaElement parentHandle= (JavaElement) this.handleStack.peek(); 355 String nameString= new String (typeInfo.name); 356 SourceType handle = new SourceType(parentHandle, nameString); resolveDuplicates(handle); 358 359 SourceTypeElementInfo info = 360 typeInfo.anonymousMember ? 361 new SourceTypeElementInfo() { 362 public boolean isAnonymousMember() { 363 return true; 364 } 365 } : 366 new SourceTypeElementInfo(); 367 info.setHandle(handle); 368 info.setSourceRangeStart(typeInfo.declarationStart); 369 info.setFlags(typeInfo.modifiers); 370 info.setNameSourceStart(typeInfo.nameSourceStart); 371 info.setNameSourceEnd(typeInfo.nameSourceEnd); 372 JavaModelManager manager = JavaModelManager.getJavaModelManager(); 373 char[] superclass = typeInfo.superclass; 374 info.setSuperclassName(superclass == null ? null : manager.intern(superclass)); 375 char[][] superinterfaces = typeInfo.superinterfaces; 376 for (int i = 0, length = superinterfaces == null ? 0 : superinterfaces.length; i < length; i++) 377 superinterfaces[i] = manager.intern(superinterfaces[i]); 378 info.setSuperInterfaceNames(superinterfaces); 379 info.addCategories(handle, typeInfo.categories); 380 if (parentHandle.getElementType() == IJavaElement.TYPE) 381 ((SourceTypeElementInfo) parentInfo).addCategories(handle, typeInfo.categories); 382 addToChildren(parentInfo, handle); 383 this.unitInfo.addAnnotationPositions(handle, typeInfo.annotationPositions); 384 this.newElements.put(handle, info); 385 this.infoStack.push(info); 386 this.handleStack.push(handle); 387 388 if (typeInfo.typeParameters != null) { 389 for (int i = 0, length = typeInfo.typeParameters.length; i < length; i++) { 390 TypeParameterInfo typeParameterInfo = typeInfo.typeParameters[i]; 391 enterTypeParameter(typeParameterInfo); 392 exitMember(typeParameterInfo.declarationEnd); 393 } 394 } 395 } 396 protected void enterTypeParameter(TypeParameterInfo typeParameterInfo) { 397 JavaElementInfo parentInfo = (JavaElementInfo) this.infoStack.peek(); 398 JavaElement parentHandle = (JavaElement) this.handleStack.peek(); 399 String nameString = new String (typeParameterInfo.name); 400 TypeParameter handle = new TypeParameter(parentHandle, nameString); resolveDuplicates(handle); 402 403 TypeParameterElementInfo info = new TypeParameterElementInfo(); 404 info.setSourceRangeStart(typeParameterInfo.declarationStart); 405 info.nameStart = typeParameterInfo.nameSourceStart; 406 info.nameEnd = typeParameterInfo.nameSourceEnd; 407 info.bounds = typeParameterInfo.bounds; 408 if (parentInfo instanceof SourceTypeElementInfo) { 409 SourceTypeElementInfo elementInfo = (SourceTypeElementInfo) parentInfo; 410 ITypeParameter[] typeParameters = elementInfo.typeParameters; 411 int length = typeParameters.length; 412 System.arraycopy(typeParameters, 0, typeParameters = new ITypeParameter[length+1], 0, length); 413 typeParameters[length] = handle; 414 elementInfo.typeParameters = typeParameters; 415 } else { 416 SourceMethodElementInfo elementInfo = (SourceMethodElementInfo) parentInfo; 417 ITypeParameter[] typeParameters = elementInfo.typeParameters; 418 int length = typeParameters.length; 419 System.arraycopy(typeParameters, 0, typeParameters = new ITypeParameter[length+1], 0, length); 420 typeParameters[length] = handle; 421 elementInfo.typeParameters = typeParameters; 422 } 423 this.unitInfo.addAnnotationPositions(handle, typeParameterInfo.annotationPositions); 424 this.newElements.put(handle, info); 425 this.infoStack.push(info); 426 this.handleStack.push(handle); 427 } 428 431 public void exitCompilationUnit(int declarationEnd) { 432 if (this.importContainerInfo != null) { 434 setChildren(this.importContainerInfo); 435 } 436 437 setChildren(this.unitInfo); 439 440 this.unitInfo.setSourceLength(declarationEnd + 1); 441 442 this.unitInfo.setIsStructureKnown(!this.hasSyntaxErrors); 444 } 445 448 public void exitConstructor(int declarationEnd) { 449 exitMember(declarationEnd); 450 } 451 454 public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) { 455 SourceFieldElementInfo info = (SourceFieldElementInfo) this.infoStack.pop(); 456 info.setSourceRangeEnd(declarationSourceEnd); 457 setChildren(info); 458 459 if (initializationStart != -1) { 461 int flags = info.flags; 462 Object typeInfo; 463 if (Flags.isStatic(flags) && Flags.isFinal(flags) 464 || ((typeInfo = this.infoStack.peek()) instanceof SourceTypeElementInfo 465 && (Flags.isInterface(((SourceTypeElementInfo)typeInfo).flags)))) { 466 int length = declarationEnd - initializationStart; 467 if (length > 0) { 468 char[] initializer = new char[length]; 469 System.arraycopy(this.parser.scanner.source, initializationStart, initializer, 0, length); 470 info.initializationSource = initializer; 471 } 472 } 473 } 474 this.handleStack.pop(); 475 } 476 479 public void exitInitializer(int declarationEnd) { 480 exitMember(declarationEnd); 481 } 482 485 protected void exitMember(int declarationEnd) { 486 SourceRefElementInfo info = (SourceRefElementInfo) this.infoStack.pop(); 487 info.setSourceRangeEnd(declarationEnd); 488 setChildren(info); 489 this.handleStack.pop(); 490 } 491 494 public void exitMethod(int declarationEnd, int defaultValueStart, int defaultValueEnd) { 495 SourceMethodElementInfo info = (SourceMethodElementInfo) this.infoStack.pop(); 496 info.setSourceRangeEnd(declarationEnd); 497 setChildren(info); 498 499 if (info.isAnnotationMethod()) { 501 SourceAnnotationMethodInfo annotationMethodInfo = (SourceAnnotationMethodInfo) info; 502 annotationMethodInfo.defaultValueStart = defaultValueStart; 503 annotationMethodInfo.defaultValueEnd = defaultValueEnd; 504 } 505 this.handleStack.pop(); 506 } 507 510 public void exitType(int declarationEnd) { 511 512 exitMember(declarationEnd); 513 } 514 518 protected void resolveDuplicates(SourceRefElement handle) { 519 while (this.newElements.containsKey(handle)) { 520 handle.occurrenceCount++; 521 } 522 } 523 private void setChildren(JavaElementInfo info) { 524 ArrayList childrenList = (ArrayList ) this.children.get(info); 525 if (childrenList != null) { 526 int length = childrenList.size(); 527 IJavaElement[] elements = new IJavaElement[length]; 528 childrenList.toArray(elements); 529 info.children = elements; 530 } 531 } 532 } 533 | Popular Tags |