1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import com.sun.javadoc.*; 18 import com.sun.tools.doclets.*; 19 import org.clearsilver.HDF; 20 import org.clearsilver.CS; 21 import java.util.ArrayList; 22 import java.util.HashMap; 23 import java.util.HashSet; 24 25 public class Converter 26 { 27 private static RootDoc root; 28 makeInfo(RootDoc r)29 public static void makeInfo(RootDoc r) 30 { 31 root = r; 32 33 int N, i; 34 35 // create the objects 36 ClassDoc[] classDocs = r.classes(); 37 N = classDocs.length; 38 for (i=0; i<N; i++) { 39 Converter.obtainClass(classDocs[i]); 40 } 41 ArrayList<ClassInfo> classesNeedingInit2 = new ArrayList<ClassInfo>(); 42 // fill in the fields that reference other classes 43 while (mClassesNeedingInit.size() > 0) { 44 i = mClassesNeedingInit.size()-1; 45 ClassNeedingInit clni = mClassesNeedingInit.get(i); 46 mClassesNeedingInit.remove(i); 47 48 initClass(clni.c, clni.cl); 49 classesNeedingInit2.add(clni.cl); 50 } 51 mClassesNeedingInit = null; 52 for (ClassInfo cl: classesNeedingInit2) { 53 cl.init2(); 54 } 55 56 finishAnnotationValueInit(); 57 58 // fill in the "root" stuff 59 mRootClasses = Converter.convertClasses(r.classes()); 60 } 61 62 private static ClassInfo[] mRootClasses; rootClasses()63 public static ClassInfo[] rootClasses() 64 { 65 return mRootClasses; 66 } 67 allClasses()68 public static ClassInfo[] allClasses() { 69 return (ClassInfo[])mClasses.all(); 70 } 71 initClass(ClassDoc c, ClassInfo cl)72 private static void initClass(ClassDoc c, ClassInfo cl) 73 { 74 MethodDoc[] annotationElements; 75 if (c instanceof AnnotationTypeDoc) { 76 annotationElements = ((AnnotationTypeDoc)c).elements(); 77 } else { 78 annotationElements = new MethodDoc[0]; 79 } 80 cl.init(Converter.obtainType(c), 81 Converter.convertClasses(c.interfaces()), 82 Converter.convertTypes(c.interfaceTypes()), 83 Converter.convertClasses(c.innerClasses()), 84 Converter.convertMethods(c.constructors(false)), 85 Converter.convertMethods(c.methods(false)), 86 Converter.convertMethods(annotationElements), 87 Converter.convertFields(c.fields(false)), 88 Converter.convertFields(c.enumConstants()), 89 Converter.obtainPackage(c.containingPackage()), 90 Converter.obtainClass(c.containingClass()), 91 Converter.obtainClass(c.superclass()), 92 Converter.obtainType(c.superclassType()), 93 Converter.convertAnnotationInstances(c.annotations()) 94 ); 95 cl.setHiddenMethods(Converter.getHiddenMethods(c.methods(false))); 96 cl.setNonWrittenConstructors(Converter.convertNonWrittenConstructors(c.constructors(false))); 97 cl.init3(Converter.convertTypes(c.typeParameters()), Converter.convertClasses(c.innerClasses(false))); 98 } 99 obtainClass(String className)100 public static ClassInfo obtainClass(String className) 101 { 102 return Converter.obtainClass(root.classNamed(className)); 103 } 104 obtainPackage(String packageName)105 public static PackageInfo obtainPackage(String packageName) 106 { 107 return Converter.obtainPackage(root.packageNamed(packageName)); 108 } 109 convertTag(Tag tag)110 private static TagInfo convertTag(Tag tag) 111 { 112 return new TextTagInfo(tag.name(), tag.kind(), tag.text(), 113 Converter.convertSourcePosition(tag.position())); 114 } 115 convertThrowsTag(ThrowsTag tag, ContainerInfo base)116 private static ThrowsTagInfo convertThrowsTag(ThrowsTag tag, 117 ContainerInfo base) 118 { 119 return new ThrowsTagInfo(tag.name(), tag.text(), tag.kind(), 120 Converter.obtainClass(tag.exception()), 121 tag.exceptionComment(), base, 122 Converter.convertSourcePosition(tag.position())); 123 } 124 convertParamTag(ParamTag tag, ContainerInfo base)125 private static ParamTagInfo convertParamTag(ParamTag tag, 126 ContainerInfo base) 127 { 128 return new ParamTagInfo(tag.name(), tag.kind(), tag.text(), 129 tag.isTypeParameter(), tag.parameterComment(), 130 tag.parameterName(), 131 base, 132 Converter.convertSourcePosition(tag.position())); 133 } 134 convertSeeTag(SeeTag tag, ContainerInfo base)135 private static SeeTagInfo convertSeeTag(SeeTag tag, ContainerInfo base) 136 { 137 return new SeeTagInfo(tag.name(), tag.kind(), tag.text(), base, 138 Converter.convertSourcePosition(tag.position())); 139 } 140 convertSourcePosition(SourcePosition sp)141 private static SourcePositionInfo convertSourcePosition(SourcePosition sp) 142 { 143 if (sp == null) { 144 return null; 145 } 146 return new SourcePositionInfo(sp.file().toString(), sp.line(), 147 sp.column()); 148 } 149 convertTags(Tag[] tags, ContainerInfo base)150 public static TagInfo[] convertTags(Tag[] tags, ContainerInfo base) 151 { 152 int len = tags.length; 153 TagInfo[] out = new TagInfo[len]; 154 for (int i=0; i<len; i++) { 155 Tag t = tags[i]; 156 /* 157 System.out.println("Tag name='" + t.name() + "' kind='" 158 + t.kind() + "'"); 159 */ 160 if (t instanceof SeeTag) { 161 out[i] = Converter.convertSeeTag((SeeTag)t, base); 162 } 163 else if (t instanceof ThrowsTag) { 164 out[i] = Converter.convertThrowsTag((ThrowsTag)t, base); 165 } 166 else if (t instanceof ParamTag) { 167 out[i] = Converter.convertParamTag((ParamTag)t, base); 168 } 169 else { 170 out[i] = Converter.convertTag(t); 171 } 172 } 173 return out; 174 } 175 convertClasses(ClassDoc[] classes)176 public static ClassInfo[] convertClasses(ClassDoc[] classes) 177 { 178 if (classes == null) return null; 179 int N = classes.length; 180 ClassInfo[] result = new ClassInfo[N]; 181 for (int i=0; i<N; i++) { 182 result[i] = Converter.obtainClass(classes[i]); 183 } 184 return result; 185 } 186 convertParameter(Parameter p, SourcePosition pos)187 private static ParameterInfo convertParameter(Parameter p, SourcePosition pos) 188 { 189 if (p == null) return null; 190 ParameterInfo pi = new ParameterInfo(p.name(), p.typeName(), 191 Converter.obtainType(p.type()), 192 Converter.convertSourcePosition(pos)); 193 return pi; 194 } 195 convertParameters(Parameter[] p, MemberDoc m)196 private static ParameterInfo[] convertParameters(Parameter[] p, MemberDoc m) 197 { 198 SourcePosition pos = m.position(); 199 int len = p.length; 200 ParameterInfo[] q = new ParameterInfo[len]; 201 for (int i=0; i<len; i++) { 202 q[i] = Converter.convertParameter(p[i], pos); 203 } 204 return q; 205 } 206 convertTypes(Type[] p)207 private static TypeInfo[] convertTypes(Type[] p) 208 { 209 if (p == null) return null; 210 int len = p.length; 211 TypeInfo[] q = new TypeInfo[len]; 212 for (int i=0; i<len; i++) { 213 q[i] = Converter.obtainType(p[i]); 214 } 215 return q; 216 } 217 Converter()218 private Converter() 219 { 220 } 221 222 private static class ClassNeedingInit 223 { ClassNeedingInit(ClassDoc c, ClassInfo cl)224 ClassNeedingInit(ClassDoc c, ClassInfo cl) 225 { 226 this.c = c; 227 this.cl = cl; 228 } 229 ClassDoc c; 230 ClassInfo cl; 231 }; 232 private static ArrayList<ClassNeedingInit> mClassesNeedingInit 233 = new ArrayList<ClassNeedingInit>(); 234 obtainClass(ClassDoc o)235 static ClassInfo obtainClass(ClassDoc o) 236 { 237 return (ClassInfo)mClasses.obtain(o); 238 } 239 private static Cache mClasses = new Cache() 240 { 241 @Override 242 protected Object make(Object o) 243 { 244 ClassDoc c = (ClassDoc)o; 245 ClassInfo cl = new ClassInfo( 246 c, 247 c.getRawCommentText(), 248 Converter.convertSourcePosition(c.position()), 249 c.isPublic(), 250 c.isProtected(), 251 c.isPackagePrivate(), 252 c.isPrivate(), 253 c.isStatic(), 254 c.isInterface(), 255 c.isAbstract(), 256 c.isOrdinaryClass(), 257 c.isException(), 258 c.isError(), 259 c.isEnum(), 260 (c instanceof AnnotationTypeDoc), 261 c.isFinal(), 262 c.isIncluded(), 263 c.name(), 264 c.qualifiedName(), 265 c.qualifiedTypeName(), 266 c.isPrimitive()); 267 if (mClassesNeedingInit != null) { 268 mClassesNeedingInit.add(new ClassNeedingInit(c, cl)); 269 } 270 return cl; 271 } 272 @Override 273 protected void made(Object o, Object r) 274 { 275 if (mClassesNeedingInit == null) { 276 initClass((ClassDoc)o, (ClassInfo)r); 277 ((ClassInfo)r).init2(); 278 } 279 } 280 @Override 281 ClassInfo[] all() 282 { 283 return (ClassInfo[])mCache.values().toArray(new ClassInfo[mCache.size()]); 284 } 285 }; 286 getHiddenMethods(MethodDoc[] methods)287 private static MethodInfo[] getHiddenMethods(MethodDoc[] methods){ 288 if (methods == null) return null; 289 ArrayList<MethodInfo> out = new ArrayList<MethodInfo>(); 290 int N = methods.length; 291 for (int i=0; i<N; i++) { 292 MethodInfo m = Converter.obtainMethod(methods[i]); 293 //System.out.println(m.toString() + ": "); 294 //for (TypeInfo ti : m.getTypeParameters()){ 295 // if (ti.asClassInfo() != null){ 296 //System.out.println(" " +ti.asClassInfo().toString()); 297 //} else { 298 //System.out.println(" null"); 299 //} 300 //} 301 if (m.isHidden()) { 302 out.add(m); 303 } 304 } 305 return out.toArray(new MethodInfo[out.size()]); 306 } 307 308 /** 309 * Convert MethodDoc[] into MethodInfo[]. Also filters according 310 * to the -private, -public option, because the filtering doesn't seem 311 * to be working in the ClassDoc.constructors(boolean) call. 312 */ convertMethods(MethodDoc[] methods)313 private static MethodInfo[] convertMethods(MethodDoc[] methods) 314 { 315 if (methods == null) return null; 316 ArrayList<MethodInfo> out = new ArrayList<MethodInfo>(); 317 int N = methods.length; 318 for (int i=0; i<N; i++) { 319 MethodInfo m = Converter.obtainMethod(methods[i]); 320 //System.out.println(m.toString() + ": "); 321 //for (TypeInfo ti : m.getTypeParameters()){ 322 // if (ti.asClassInfo() != null){ 323 //System.out.println(" " +ti.asClassInfo().toString()); 324 //} else { 325 //System.out.println(" null"); 326 //} 327 //} 328 if (m.checkLevel()) { 329 out.add(m); 330 } 331 } 332 return out.toArray(new MethodInfo[out.size()]); 333 } 334 convertMethods(ConstructorDoc[] methods)335 private static MethodInfo[] convertMethods(ConstructorDoc[] methods) 336 { 337 if (methods == null) return null; 338 ArrayList<MethodInfo> out = new ArrayList<MethodInfo>(); 339 int N = methods.length; 340 for (int i=0; i<N; i++) { 341 MethodInfo m = Converter.obtainMethod(methods[i]); 342 if (m.checkLevel()) { 343 out.add(m); 344 } 345 } 346 return out.toArray(new MethodInfo[out.size()]); 347 } 348 convertNonWrittenConstructors(ConstructorDoc[] methods)349 private static MethodInfo[] convertNonWrittenConstructors(ConstructorDoc[] methods) 350 { 351 if (methods == null) return null; 352 ArrayList<MethodInfo> out = new ArrayList<MethodInfo>(); 353 int N = methods.length; 354 for (int i=0; i<N; i++) { 355 MethodInfo m = Converter.obtainMethod(methods[i]); 356 if (!m.checkLevel()) { 357 out.add(m); 358 } 359 } 360 return out.toArray(new MethodInfo[out.size()]); 361 } 362 obtainMethod(MethodDoc o)363 private static MethodInfo obtainMethod(MethodDoc o) 364 { 365 return (MethodInfo)mMethods.obtain(o); 366 } obtainMethod(ConstructorDoc o)367 private static MethodInfo obtainMethod(ConstructorDoc o) 368 { 369 return (MethodInfo)mMethods.obtain(o); 370 } 371 private static Cache mMethods = new Cache() 372 { 373 @Override 374 protected Object make(Object o) 375 { 376 if (o instanceof AnnotationTypeElementDoc) { 377 AnnotationTypeElementDoc m = (AnnotationTypeElementDoc)o; 378 MethodInfo result = new MethodInfo( 379 m.getRawCommentText(), 380 Converter.convertTypes(m.typeParameters()), 381 m.name(), m.signature(), 382 Converter.obtainClass(m.containingClass()), 383 Converter.obtainClass(m.containingClass()), 384 m.isPublic(), m.isProtected(), 385 m.isPackagePrivate(), m.isPrivate(), 386 m.isFinal(), m.isStatic(), m.isSynthetic(), 387 m.isAbstract(), m.isSynchronized(), m.isNative(), true, 388 "annotationElement", 389 m.flatSignature(), 390 Converter.obtainMethod(m.overriddenMethod()), 391 Converter.obtainType(m.returnType()), 392 Converter.convertParameters(m.parameters(), m), 393 Converter.convertClasses(m.thrownExceptions()), 394 Converter.convertSourcePosition(m.position()), 395 Converter.convertAnnotationInstances(m.annotations()) 396 ); 397 result.setVarargs(m.isVarArgs()); 398 result.init(Converter.obtainAnnotationValue(m.defaultValue(), result)); 399 return result; 400 } 401 else if (o instanceof MethodDoc) { 402 MethodDoc m = (MethodDoc)o; 403 MethodInfo result = new MethodInfo( 404 m.getRawCommentText(), 405 Converter.convertTypes(m.typeParameters()), 406 m.name(), m.signature(), 407 Converter.obtainClass(m.containingClass()), 408 Converter.obtainClass(m.containingClass()), 409 m.isPublic(), m.isProtected(), 410 m.isPackagePrivate(), m.isPrivate(), 411 m.isFinal(), m.isStatic(), m.isSynthetic(), 412 m.isAbstract(), m.isSynchronized(), m.isNative(), false, 413 "method", 414 m.flatSignature(), 415 Converter.obtainMethod(m.overriddenMethod()), 416 Converter.obtainType(m.returnType()), 417 Converter.convertParameters(m.parameters(), m), 418 Converter.convertClasses(m.thrownExceptions()), 419 Converter.convertSourcePosition(m.position()), 420 Converter.convertAnnotationInstances(m.annotations()) 421 ); 422 result.setVarargs(m.isVarArgs()); 423 result.init(null); 424 return result; 425 } 426 else { 427 ConstructorDoc m = (ConstructorDoc)o; 428 MethodInfo result = new MethodInfo( 429 m.getRawCommentText(), 430 Converter.convertTypes(m.typeParameters()), 431 m.name(), m.signature(), 432 Converter.obtainClass(m.containingClass()), 433 Converter.obtainClass(m.containingClass()), 434 m.isPublic(), m.isProtected(), 435 m.isPackagePrivate(), m.isPrivate(), 436 m.isFinal(), m.isStatic(), m.isSynthetic(), 437 false, m.isSynchronized(), m.isNative(), false, 438 "constructor", 439 m.flatSignature(), 440 null, 441 null, 442 Converter.convertParameters(m.parameters(), m), 443 Converter.convertClasses(m.thrownExceptions()), 444 Converter.convertSourcePosition(m.position()), 445 Converter.convertAnnotationInstances(m.annotations()) 446 ); 447 result.setVarargs(m.isVarArgs()); 448 result.init(null); 449 return result; 450 } 451 } 452 }; 453 454 convertFields(FieldDoc[] fields)455 private static FieldInfo[] convertFields(FieldDoc[] fields) 456 { 457 if (fields == null) return null; 458 ArrayList<FieldInfo> out = new ArrayList<FieldInfo>(); 459 int N = fields.length; 460 for (int i=0; i<N; i++) { 461 FieldInfo f = Converter.obtainField(fields[i]); 462 if (f.checkLevel()) { 463 out.add(f); 464 } 465 } 466 return out.toArray(new FieldInfo[out.size()]); 467 } 468 obtainField(FieldDoc o)469 private static FieldInfo obtainField(FieldDoc o) 470 { 471 return (FieldInfo)mFields.obtain(o); 472 } obtainField(ConstructorDoc o)473 private static FieldInfo obtainField(ConstructorDoc o) 474 { 475 return (FieldInfo)mFields.obtain(o); 476 } 477 private static Cache mFields = new Cache() 478 { 479 @Override 480 protected Object make(Object o) 481 { 482 FieldDoc f = (FieldDoc)o; 483 return new FieldInfo(f.name(), 484 Converter.obtainClass(f.containingClass()), 485 Converter.obtainClass(f.containingClass()), 486 f.isPublic(), f.isProtected(), 487 f.isPackagePrivate(), f.isPrivate(), 488 f.isFinal(), f.isStatic(), f.isTransient(), f.isVolatile(), 489 f.isSynthetic(), 490 Converter.obtainType(f.type()), 491 f.getRawCommentText(), f.constantValue(), 492 Converter.convertSourcePosition(f.position()), 493 Converter.convertAnnotationInstances(f.annotations()) 494 ); 495 } 496 }; 497 obtainPackage(PackageDoc o)498 private static PackageInfo obtainPackage(PackageDoc o) 499 { 500 return (PackageInfo)mPackagees.obtain(o); 501 } 502 private static Cache mPackagees = new Cache() 503 { 504 @Override 505 protected Object make(Object o) 506 { 507 PackageDoc p = (PackageDoc)o; 508 return new PackageInfo(p, p.name(), 509 Converter.convertSourcePosition(p.position())); 510 } 511 }; 512 obtainType(Type o)513 private static TypeInfo obtainType(Type o) 514 { 515 return (TypeInfo)mTypes.obtain(o); 516 } 517 private static Cache mTypes = new Cache() 518 { 519 @Override 520 protected Object make(Object o) 521 { 522 Type t = (Type)o; 523 String simpleTypeName; 524 if (t instanceof ClassDoc) { 525 simpleTypeName = ((ClassDoc)t).name(); 526 } else { 527 simpleTypeName = t.simpleTypeName(); 528 } 529 TypeInfo ti = new TypeInfo(t.isPrimitive(), t.dimension(), 530 simpleTypeName, t.qualifiedTypeName(), 531 Converter.obtainClass(t.asClassDoc())); 532 return ti; 533 } 534 @Override 535 protected void made(Object o, Object r) 536 { 537 Type t = (Type)o; 538 TypeInfo ti = (TypeInfo)r; 539 if (t.asParameterizedType() != null) { 540 ti.setTypeArguments(Converter.convertTypes( 541 t.asParameterizedType().typeArguments())); 542 } 543 else if (t instanceof ClassDoc) { 544 ti.setTypeArguments(Converter.convertTypes(((ClassDoc)t).typeParameters())); 545 } 546 else if (t.asTypeVariable() != null) { 547 ti.setBounds(null, Converter.convertTypes((t.asTypeVariable().bounds()))); 548 ti.setIsTypeVariable(true); 549 } 550 else if (t.asWildcardType() != null) { 551 ti.setIsWildcard(true); 552 ti.setBounds(Converter.convertTypes(t.asWildcardType().superBounds()), 553 Converter.convertTypes(t.asWildcardType().extendsBounds())); 554 } 555 } 556 @Override 557 protected Object keyFor(Object o) 558 { 559 Type t = (Type)o; 560 String keyString = o.getClass().getName() + "/" + o.toString() + "/"; 561 if (t.asParameterizedType() != null){ 562 keyString += t.asParameterizedType().toString() +"/"; 563 if (t.asParameterizedType().typeArguments() != null){ 564 for(Type ty : t.asParameterizedType().typeArguments()){ 565 keyString += ty.toString() + "/"; 566 } 567 } 568 }else{ 569 keyString += "NoParameterizedType//"; 570 } 571 if (t.asTypeVariable() != null){ 572 keyString += t.asTypeVariable().toString() +"/"; 573 if (t.asTypeVariable().bounds() != null){ 574 for(Type ty : t.asTypeVariable().bounds()){ 575 keyString += ty.toString() + "/"; 576 } 577 } 578 }else{ 579 keyString += "NoTypeVariable//"; 580 } 581 if (t.asWildcardType() != null){ 582 keyString += t.asWildcardType().toString() +"/"; 583 if (t.asWildcardType().superBounds() != null){ 584 for(Type ty : t.asWildcardType().superBounds()){ 585 keyString += ty.toString() + "/"; 586 } 587 } 588 if (t.asWildcardType().extendsBounds() != null){ 589 for(Type ty : t.asWildcardType().extendsBounds()){ 590 keyString += ty.toString() + "/"; 591 } 592 } 593 }else{ 594 keyString += "NoWildCardType//"; 595 } 596 597 598 599 return keyString; 600 } 601 }; 602 603 604 obtainMember(MemberDoc o)605 private static MemberInfo obtainMember(MemberDoc o) 606 { 607 return (MemberInfo)mMembers.obtain(o); 608 } 609 private static Cache mMembers = new Cache() 610 { 611 @Override 612 protected Object make(Object o) 613 { 614 if (o instanceof MethodDoc) { 615 return Converter.obtainMethod((MethodDoc)o); 616 } 617 else if (o instanceof ConstructorDoc) { 618 return Converter.obtainMethod((ConstructorDoc)o); 619 } 620 else if (o instanceof FieldDoc) { 621 return Converter.obtainField((FieldDoc)o); 622 } 623 else { 624 return null; 625 } 626 } 627 }; 628 convertAnnotationInstances(AnnotationDesc[] orig)629 private static AnnotationInstanceInfo[] convertAnnotationInstances(AnnotationDesc[] orig) 630 { 631 int len = orig.length; 632 AnnotationInstanceInfo[] out = new AnnotationInstanceInfo[len]; 633 for (int i=0; i<len; i++) { 634 out[i] = Converter.obtainAnnotationInstance(orig[i]); 635 } 636 return out; 637 } 638 639 obtainAnnotationInstance(AnnotationDesc o)640 private static AnnotationInstanceInfo obtainAnnotationInstance(AnnotationDesc o) 641 { 642 return (AnnotationInstanceInfo)mAnnotationInstances.obtain(o); 643 } 644 private static Cache mAnnotationInstances = new Cache() 645 { 646 @Override 647 protected Object make(Object o) 648 { 649 AnnotationDesc a = (AnnotationDesc)o; 650 ClassInfo annotationType = Converter.obtainClass(a.annotationType()); 651 AnnotationDesc.ElementValuePair[] ev = a.elementValues(); 652 AnnotationValueInfo[] elementValues = new AnnotationValueInfo[ev.length]; 653 for (int i=0; i<ev.length; i++) { 654 elementValues[i] = obtainAnnotationValue(ev[i].value(), 655 Converter.obtainMethod(ev[i].element())); 656 } 657 return new AnnotationInstanceInfo(annotationType, elementValues); 658 } 659 }; 660 661 662 private abstract static class Cache 663 { put(Object key, Object value)664 void put(Object key, Object value) 665 { 666 mCache.put(key, value); 667 } obtain(Object o)668 Object obtain(Object o) 669 { 670 if (o == null ) { 671 return null; 672 } 673 Object k = keyFor(o); 674 Object r = mCache.get(k); 675 if (r == null) { 676 r = make(o); 677 mCache.put(k, r); 678 made(o, r); 679 } 680 return r; 681 } 682 protected HashMap<Object,Object> mCache = new HashMap<Object,Object>(); make(Object o)683 protected abstract Object make(Object o); made(Object o, Object r)684 protected void made(Object o, Object r) 685 { 686 } keyFor(Object o)687 protected Object keyFor(Object o) { return o; } all()688 Object[] all() { return null; } 689 } 690 691 // annotation values 692 private static HashMap<AnnotationValue,AnnotationValueInfo> mAnnotationValues = new HashMap(); 693 private static HashSet<AnnotationValue> mAnnotationValuesNeedingInit = new HashSet(); 694 obtainAnnotationValue(AnnotationValue o, MethodInfo element)695 private static AnnotationValueInfo obtainAnnotationValue(AnnotationValue o, MethodInfo element) 696 { 697 if (o == null) { 698 return null; 699 } 700 AnnotationValueInfo v = mAnnotationValues.get(o); 701 if (v != null) return v; 702 v = new AnnotationValueInfo(element); 703 mAnnotationValues.put(o, v); 704 if (mAnnotationValuesNeedingInit != null) { 705 mAnnotationValuesNeedingInit.add(o); 706 } else { 707 initAnnotationValue(o, v); 708 } 709 return v; 710 } 711 initAnnotationValue(AnnotationValue o, AnnotationValueInfo v)712 private static void initAnnotationValue(AnnotationValue o, AnnotationValueInfo v) { 713 Object orig = o.value(); 714 Object converted; 715 if (orig instanceof Type) { 716 // class literal 717 converted = Converter.obtainType((Type)orig); 718 } 719 else if (orig instanceof FieldDoc) { 720 // enum constant 721 converted = Converter.obtainField((FieldDoc)orig); 722 } 723 else if (orig instanceof AnnotationDesc) { 724 // annotation instance 725 converted = Converter.obtainAnnotationInstance((AnnotationDesc)orig); 726 } 727 else if (orig instanceof AnnotationValue[]) { 728 AnnotationValue[] old = (AnnotationValue[])orig; 729 AnnotationValueInfo[] array = new AnnotationValueInfo[old.length]; 730 for (int i=0; i<array.length; i++) { 731 array[i] = Converter.obtainAnnotationValue(old[i], null); 732 } 733 converted = array; 734 } 735 else { 736 converted = orig; 737 } 738 v.init(converted); 739 } 740 finishAnnotationValueInit()741 private static void finishAnnotationValueInit() 742 { 743 int depth = 0; 744 while (mAnnotationValuesNeedingInit.size() > 0) { 745 HashSet<AnnotationValue> set = mAnnotationValuesNeedingInit; 746 mAnnotationValuesNeedingInit = new HashSet(); 747 for (AnnotationValue o: set) { 748 AnnotationValueInfo v = mAnnotationValues.get(o); 749 initAnnotationValue(o, v); 750 } 751 depth++; 752 } 753 mAnnotationValuesNeedingInit = null; 754 } 755 } 756