1920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson/*
2920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Copyright (C) 2010 Google Inc.
3920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson *
4920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Licensed under the Apache License, Version 2.0 (the "License");
5920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * you may not use this file except in compliance with the License.
6920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * You may obtain a copy of the License at
7920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson *
8920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * http://www.apache.org/licenses/LICENSE-2.0
9920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson *
10920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Unless required by applicable law or agreed to in writing, software
11920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * distributed under the License is distributed on an "AS IS" BASIS,
12920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * See the License for the specific language governing permissions and
14920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * limitations under the License.
15920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */
16920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
17920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonpackage com.google.doclava;
18920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
19920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.sun.javadoc.*;
20920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.ArrayList;
21d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.Arrays;
22920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.HashMap;
23920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.HashSet;
24d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.ArrayList;
25920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
26920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonpublic class Converter {
27920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static RootDoc root;
28920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
29920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static void makeInfo(RootDoc r) {
30920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    root = r;
31920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
32920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int N, i;
33920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
34920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // create the objects
35920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassDoc[] classDocs = r.classes();
36920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    N = classDocs.length;
37920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (i = 0; i < N; i++) {
38920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Converter.obtainClass(classDocs[i]);
39920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
40920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<ClassInfo> classesNeedingInit2 = new ArrayList<ClassInfo>();
41920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // fill in the fields that reference other classes
42920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    while (mClassesNeedingInit.size() > 0) {
43920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      i = mClassesNeedingInit.size() - 1;
44920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassNeedingInit clni = mClassesNeedingInit.get(i);
45920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mClassesNeedingInit.remove(i);
46920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
47920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      initClass(clni.c, clni.cl);
48920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      classesNeedingInit2.add(clni.cl);
49920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
50920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mClassesNeedingInit = null;
51920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (ClassInfo cl : classesNeedingInit2) {
52920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      cl.init2();
53920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
54920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
55920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    finishAnnotationValueInit();
56920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
57920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // fill in the "root" stuff
58920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mRootClasses = Converter.convertClasses(r.classes());
59920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
60920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
61920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static ClassInfo[] mRootClasses;
62920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
63920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static ClassInfo[] rootClasses() {
64920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mRootClasses;
65920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
66920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
67920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static ClassInfo[] allClasses() {
68920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return (ClassInfo[]) mClasses.all();
69920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
70920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
71920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void initClass(ClassDoc c, ClassInfo cl) {
72920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    MethodDoc[] annotationElements;
73920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (c instanceof AnnotationTypeDoc) {
74920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      annotationElements = ((AnnotationTypeDoc) c).elements();
75920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else {
76920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      annotationElements = new MethodDoc[0];
77920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
78d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    cl.init(Converter.obtainType(c),
79d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new ArrayList<ClassInfo>(Arrays.asList(Converter.convertClasses(c.interfaces()))),
80d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new ArrayList<TypeInfo>(Arrays.asList(Converter.convertTypes(c.interfaceTypes()))),
81d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new ArrayList<ClassInfo>(Arrays.asList(Converter.convertClasses(c.innerClasses()))),
82d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new ArrayList<MethodInfo>(Arrays.asList(
83d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    Converter.convertMethods(c.constructors(false)))),
84d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new ArrayList<MethodInfo>(Arrays.asList(Converter.convertMethods(c.methods(false)))),
85d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new ArrayList<MethodInfo>(Arrays.asList(Converter.convertMethods(annotationElements))),
86d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new ArrayList<FieldInfo>(Arrays.asList(Converter.convertFields(c.fields(false)))),
87d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new ArrayList<FieldInfo>(Arrays.asList(Converter.convertFields(c.enumConstants()))),
88d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            Converter.obtainPackage(c.containingPackage()),
89d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            Converter.obtainClass(c.containingClass()),
90d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            Converter.obtainClass(c.superclass()), Converter.obtainType(c.superclassType()),
91d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new ArrayList<AnnotationInstanceInfo>(Arrays.asList(
92d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    Converter.convertAnnotationInstances(c.annotations()))));
93d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
94d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    cl.setHiddenMethods(
95d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new ArrayList<MethodInfo>(Arrays.asList(Converter.getHiddenMethods(c.methods(false)))));
96d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    cl.setNonWrittenConstructors(
97d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new ArrayList<MethodInfo>(Arrays.asList(Converter.convertNonWrittenConstructors(
98d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    c.constructors(false)))));
99d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    cl.init3(
100d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new ArrayList<TypeInfo>(Arrays.asList(Converter.convertTypes(c.typeParameters()))),
101d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new ArrayList<ClassInfo>(Arrays.asList(
102d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    Converter.convertClasses(c.innerClasses(false)))));
103920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
104920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
105920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static ClassInfo obtainClass(String className) {
106920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return Converter.obtainClass(root.classNamed(className));
107920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
108920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
109920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static PackageInfo obtainPackage(String packageName) {
110920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return Converter.obtainPackage(root.packageNamed(packageName));
111920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
112920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
113920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static TagInfo convertTag(Tag tag) {
114d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    return new TextTagInfo(tag.name(), tag.kind(), tag.text(),
115d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            Converter.convertSourcePosition(tag.position()));
116920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
117920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
118920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static ThrowsTagInfo convertThrowsTag(ThrowsTag tag, ContainerInfo base) {
119920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return new ThrowsTagInfo(tag.name(), tag.text(), tag.kind(), Converter.obtainClass(tag
120920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        .exception()), tag.exceptionComment(), base, Converter
121920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        .convertSourcePosition(tag.position()));
122920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
123920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
124920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static ParamTagInfo convertParamTag(ParamTag tag, ContainerInfo base) {
125920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return new ParamTagInfo(tag.name(), tag.kind(), tag.text(), tag.isTypeParameter(), tag
126920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        .parameterComment(), tag.parameterName(), base, Converter.convertSourcePosition(tag
127920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        .position()));
128920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
129920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
130920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static SeeTagInfo convertSeeTag(SeeTag tag, ContainerInfo base) {
131920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return new SeeTagInfo(tag.name(), tag.kind(), tag.text(), base, Converter
132920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        .convertSourcePosition(tag.position()));
133920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
134920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
135920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static SourcePositionInfo convertSourcePosition(SourcePosition sp) {
136920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (sp == null) {
137920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return null;
138920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
139920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return new SourcePositionInfo(sp.file().toString(), sp.line(), sp.column());
140920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
141920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
142920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static TagInfo[] convertTags(Tag[] tags, ContainerInfo base) {
143920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int len = tags.length;
144920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TagInfo[] out = new TagInfo[len];
145920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < len; i++) {
146920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Tag t = tags[i];
147920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      /*
148920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson       * System.out.println("Tag name='" + t.name() + "' kind='" + t.kind() + "'");
149920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson       */
150920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (t instanceof SeeTag) {
151920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        out[i] = Converter.convertSeeTag((SeeTag) t, base);
152920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (t instanceof ThrowsTag) {
153920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        out[i] = Converter.convertThrowsTag((ThrowsTag) t, base);
154920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (t instanceof ParamTag) {
155920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        out[i] = Converter.convertParamTag((ParamTag) t, base);
156920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
157920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        out[i] = Converter.convertTag(t);
158920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
159920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
160920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return out;
161920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
162920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
163920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static ClassInfo[] convertClasses(ClassDoc[] classes) {
164920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (classes == null) return null;
165920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int N = classes.length;
166920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] result = new ClassInfo[N];
167920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < N; i++) {
168920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      result[i] = Converter.obtainClass(classes[i]);
169920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
170920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return result;
171920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
172920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
173920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static ParameterInfo convertParameter(Parameter p, SourcePosition pos, boolean isVarArg) {
174920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (p == null) return null;
175920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ParameterInfo pi =
176920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        new ParameterInfo(p.name(), p.typeName(), Converter.obtainType(p.type()), isVarArg,
177920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          Converter.convertSourcePosition(pos));
178920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return pi;
179920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
180920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
181920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static ParameterInfo[] convertParameters(Parameter[] p, ExecutableMemberDoc m) {
182920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    SourcePosition pos = m.position();
183920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int len = p.length;
184920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ParameterInfo[] q = new ParameterInfo[len];
185920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < len; i++) {
186920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      boolean isVarArg = (m.isVarArgs() && i == len - 1);
187920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      q[i] = Converter.convertParameter(p[i], pos, isVarArg);
188920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
189920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return q;
190920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
191920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
192920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static TypeInfo[] convertTypes(Type[] p) {
193920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (p == null) return null;
194920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int len = p.length;
195920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    TypeInfo[] q = new TypeInfo[len];
196920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < len; i++) {
197920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      q[i] = Converter.obtainType(p[i]);
198920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
199920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return q;
200920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
201920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
202920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private Converter() {}
203920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
204920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static class ClassNeedingInit {
205920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassNeedingInit(ClassDoc c, ClassInfo cl) {
206920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      this.c = c;
207920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      this.cl = cl;
208920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
209920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
210920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassDoc c;
211920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo cl;
212920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
213920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
214920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static ArrayList<ClassNeedingInit> mClassesNeedingInit =
215920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      new ArrayList<ClassNeedingInit>();
216920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
217920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  static ClassInfo obtainClass(ClassDoc o) {
218920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return (ClassInfo) mClasses.obtain(o);
219920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
220920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
221920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static Cache mClasses = new Cache() {
222920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    @Override
223920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected Object make(Object o) {
224920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassDoc c = (ClassDoc) o;
225920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo cl =
226920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          new ClassInfo(c, c.getRawCommentText(), Converter.convertSourcePosition(c.position()), c
227920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              .isPublic(), c.isProtected(), c.isPackagePrivate(), c.isPrivate(), c.isStatic(), c
228920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              .isInterface(), c.isAbstract(), c.isOrdinaryClass(), c.isException(), c.isError(), c
229920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              .isEnum(), (c instanceof AnnotationTypeDoc), c.isFinal(), c.isIncluded(), c.name(), c
230920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              .qualifiedName(), c.qualifiedTypeName(), c.isPrimitive());
231920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (mClassesNeedingInit != null) {
232920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        mClassesNeedingInit.add(new ClassNeedingInit(c, cl));
233920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
234920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return cl;
235920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
236920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
237920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    @Override
238920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected void made(Object o, Object r) {
239920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (mClassesNeedingInit == null) {
240920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        initClass((ClassDoc) o, (ClassInfo) r);
241920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        ((ClassInfo) r).init2();
242920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
243920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
244920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
245920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    @Override
246920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ClassInfo[] all() {
247920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return mCache.values().toArray(new ClassInfo[mCache.size()]);
248920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
249920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  };
250920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
251920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static MethodInfo[] getHiddenMethods(MethodDoc[] methods) {
252920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (methods == null) return null;
253920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<MethodInfo> out = new ArrayList<MethodInfo>();
254920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int N = methods.length;
255920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < N; i++) {
256920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      MethodInfo m = Converter.obtainMethod(methods[i]);
257920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // System.out.println(m.toString() + ": ");
258920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // for (TypeInfo ti : m.getTypeParameters()){
259920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // if (ti.asClassInfo() != null){
260920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // System.out.println(" " +ti.asClassInfo().toString());
261920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // } else {
262920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // System.out.println(" null");
263920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // }
264920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // }
265920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (m.isHidden()) {
266920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        out.add(m);
267920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
268920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
269920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return out.toArray(new MethodInfo[out.size()]);
270920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
271920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
272920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  /**
273920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * Convert MethodDoc[] into MethodInfo[]. Also filters according to the -private, -public option,
274920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   * because the filtering doesn't seem to be working in the ClassDoc.constructors(boolean) call.
275920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson   */
276920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static MethodInfo[] convertMethods(MethodDoc[] methods) {
277920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (methods == null) return null;
278920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<MethodInfo> out = new ArrayList<MethodInfo>();
279920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int N = methods.length;
280920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < N; i++) {
281920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      MethodInfo m = Converter.obtainMethod(methods[i]);
282920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // System.out.println(m.toString() + ": ");
283920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // for (TypeInfo ti : m.getTypeParameters()){
284920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // if (ti.asClassInfo() != null){
285920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // System.out.println(" " +ti.asClassInfo().toString());
286920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // } else {
287920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // System.out.println(" null");
288920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // }
289920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // }
290920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (m.checkLevel()) {
291920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        out.add(m);
292920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
293920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
294920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return out.toArray(new MethodInfo[out.size()]);
295920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
296920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
297920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static MethodInfo[] convertMethods(ConstructorDoc[] methods) {
298920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (methods == null) return null;
299920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<MethodInfo> out = new ArrayList<MethodInfo>();
300920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int N = methods.length;
301920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < N; i++) {
302920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      MethodInfo m = Converter.obtainMethod(methods[i]);
303920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (m.checkLevel()) {
304920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        out.add(m);
305920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
306920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
307920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return out.toArray(new MethodInfo[out.size()]);
308920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
309920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
310920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static MethodInfo[] convertNonWrittenConstructors(ConstructorDoc[] methods) {
311920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (methods == null) return null;
312920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<MethodInfo> out = new ArrayList<MethodInfo>();
313920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int N = methods.length;
314920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < N; i++) {
315920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      MethodInfo m = Converter.obtainMethod(methods[i]);
316920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (!m.checkLevel()) {
317920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        out.add(m);
318920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
319920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
320920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return out.toArray(new MethodInfo[out.size()]);
321920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
322920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
323920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static MethodInfo obtainMethod(MethodDoc o) {
324920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return (MethodInfo) mMethods.obtain(o);
325920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
326920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
327920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static MethodInfo obtainMethod(ConstructorDoc o) {
328920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return (MethodInfo) mMethods.obtain(o);
329920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
330920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
331920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static Cache mMethods = new Cache() {
332920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    @Override
333920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected Object make(Object o) {
334920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (o instanceof AnnotationTypeElementDoc) {
335920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        AnnotationTypeElementDoc m = (AnnotationTypeElementDoc) o;
336920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        MethodInfo result =
337d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new MethodInfo(m.getRawCommentText(),
338d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    new ArrayList<TypeInfo>(Arrays.asList(
339d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                            Converter.convertTypes(m.typeParameters()))),
340d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    m.name(), m.signature(), Converter.obtainClass(m.containingClass()),
341d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    Converter.obtainClass(m.containingClass()), m.isPublic(), m.isProtected(), m
342d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    .isPackagePrivate(), m.isPrivate(), m.isFinal(), m.isStatic(), m.isSynthetic(),
343d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    m.isAbstract(), m.isSynchronized(), m.isNative(), true, "annotationElement",
344d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    m.flatSignature(), Converter.obtainMethod(m.overriddenMethod()),
345d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    Converter.obtainType(m.returnType()),
346d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    new ArrayList<ParameterInfo>(Arrays.asList(
347d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                            Converter.convertParameters(m.parameters(), m))),
348d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    new ArrayList<ClassInfo>(Arrays.asList(Converter.convertClasses(
349d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                            m.thrownExceptions()))), Converter.convertSourcePosition(m.position()),
350d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    new ArrayList<AnnotationInstanceInfo>(Arrays.asList(
351d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                            Converter.convertAnnotationInstances(m.annotations()))));
352920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        result.setVarargs(m.isVarArgs());
353920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        result.init(Converter.obtainAnnotationValue(m.defaultValue(), result));
354920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return result;
355920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (o instanceof MethodDoc) {
356920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        MethodDoc m = (MethodDoc) o;
357920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        MethodInfo result =
358d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new MethodInfo(m.getRawCommentText(),
359d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    new ArrayList<TypeInfo>(Arrays.asList(
360d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                            Converter.convertTypes(m.typeParameters()))), m.name(), m.signature(),
361d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    Converter.obtainClass(m.containingClass()),
362d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    Converter.obtainClass(m.containingClass()), m.isPublic(), m.isProtected(),
363d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    m.isPackagePrivate(), m.isPrivate(), m.isFinal(), m.isStatic(), m.isSynthetic(),
364d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    m.isAbstract(), m.isSynchronized(), m.isNative(), false, "method",
365d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    m.flatSignature(), Converter.obtainMethod(m.overriddenMethod()),
366d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    Converter.obtainType(m.returnType()),
367d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    new ArrayList<ParameterInfo>(Arrays.asList(
368d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                            Converter.convertParameters(m.parameters(), m))),
369d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    new ArrayList<ClassInfo>(Arrays.asList(
370d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                            Converter.convertClasses(m.thrownExceptions()))),
371d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    Converter.convertSourcePosition(m.position()),
372d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    new ArrayList<AnnotationInstanceInfo>(Arrays.asList(
373d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                            Converter.convertAnnotationInstances(m.annotations()))));
374920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        result.setVarargs(m.isVarArgs());
375920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        result.init(null);
376920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return result;
377920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
378920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        ConstructorDoc m = (ConstructorDoc) o;
379920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        MethodInfo result =
380d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            new MethodInfo(m.getRawCommentText(), new ArrayList<TypeInfo>(Arrays.asList(Converter.convertTypes(m.typeParameters()))), m
381920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                .name(), m.signature(), Converter.obtainClass(m.containingClass()), Converter
382920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                .obtainClass(m.containingClass()), m.isPublic(), m.isProtected(), m
383920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                .isPackagePrivate(), m.isPrivate(), m.isFinal(), m.isStatic(), m.isSynthetic(),
384920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson                false, m.isSynchronized(), m.isNative(), false, "constructor", m.flatSignature(),
385d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                null, null, new ArrayList<ParameterInfo>(Arrays.asList(Converter.convertParameters(m.parameters(), m))),
386d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                new ArrayList<ClassInfo>(Arrays.asList(Converter.convertClasses(m.thrownExceptions()))), Converter.convertSourcePosition(m
387d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                    .position()), new ArrayList<AnnotationInstanceInfo>(Arrays.asList(Converter.convertAnnotationInstances(m.annotations()))));
388920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        result.setVarargs(m.isVarArgs());
389920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        result.init(null);
390920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return result;
391920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
392920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
393920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  };
394920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
395920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
396920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static FieldInfo[] convertFields(FieldDoc[] fields) {
397920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (fields == null) return null;
398920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    ArrayList<FieldInfo> out = new ArrayList<FieldInfo>();
399920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int N = fields.length;
400920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < N; i++) {
401920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      FieldInfo f = Converter.obtainField(fields[i]);
402920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (f.checkLevel()) {
403920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        out.add(f);
404920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
405920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
406920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return out.toArray(new FieldInfo[out.size()]);
407920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
408920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
409920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static FieldInfo obtainField(FieldDoc o) {
410920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return (FieldInfo) mFields.obtain(o);
411920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
412920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
413920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static FieldInfo obtainField(ConstructorDoc o) {
414920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return (FieldInfo) mFields.obtain(o);
415920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
416920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
417920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static Cache mFields = new Cache() {
418920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    @Override
419920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected Object make(Object o) {
420920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      FieldDoc f = (FieldDoc) o;
421920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return new FieldInfo(f.name(), Converter.obtainClass(f.containingClass()), Converter
422920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          .obtainClass(f.containingClass()), f.isPublic(), f.isProtected(), f.isPackagePrivate(), f
423920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          .isPrivate(), f.isFinal(), f.isStatic(), f.isTransient(), f.isVolatile(),
424920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          f.isSynthetic(), Converter.obtainType(f.type()), f.getRawCommentText(),
425d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein          f.constantValue(), Converter.convertSourcePosition(f.position()),
426d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein          new ArrayList<AnnotationInstanceInfo>(Arrays.asList(Converter
427d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein              .convertAnnotationInstances(f.annotations()))));
428920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
429920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  };
430920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
431920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static PackageInfo obtainPackage(PackageDoc o) {
432920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return (PackageInfo) mPackagees.obtain(o);
433920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
434920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
435920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static Cache mPackagees = new Cache() {
436920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    @Override
437920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected Object make(Object o) {
438920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      PackageDoc p = (PackageDoc) o;
439920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return new PackageInfo(p, p.name(), Converter.convertSourcePosition(p.position()));
440920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
441920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  };
442920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
443920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static TypeInfo obtainType(Type o) {
444920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return (TypeInfo) mTypes.obtain(o);
445920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
446920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
447920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static Cache mTypes = new Cache() {
448920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    @Override
449920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected Object make(Object o) {
450920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Type t = (Type) o;
451920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String simpleTypeName;
452920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (t instanceof ClassDoc) {
453920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        simpleTypeName = ((ClassDoc) t).name();
454920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
455920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        simpleTypeName = t.simpleTypeName();
456920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
457920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      TypeInfo ti =
458920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          new TypeInfo(t.isPrimitive(), t.dimension(), simpleTypeName, t.qualifiedTypeName(),
459920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson              Converter.obtainClass(t.asClassDoc()));
460920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return ti;
461920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
462920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
463920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    @Override
464920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected void made(Object o, Object r) {
465920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Type t = (Type) o;
466920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      TypeInfo ti = (TypeInfo) r;
467920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (t.asParameterizedType() != null) {
468d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        ti.setTypeArguments(new ArrayList<TypeInfo>(Arrays.asList(Converter.convertTypes(t.asParameterizedType().typeArguments()))));
469920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (t instanceof ClassDoc) {
470d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        ti.setTypeArguments(new ArrayList<TypeInfo>(Arrays.asList(Converter.convertTypes(((ClassDoc) t).typeParameters()))));
471920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (t.asTypeVariable() != null) {
472d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        ti.setBounds(null, new ArrayList<TypeInfo>(Arrays.asList(Converter.convertTypes((t.asTypeVariable().bounds())))));
473920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        ti.setIsTypeVariable(true);
474920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (t.asWildcardType() != null) {
475920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        ti.setIsWildcard(true);
476d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        ti.setBounds(new ArrayList<TypeInfo>(Arrays.asList(Converter.convertTypes(t.asWildcardType().superBounds()))),
477d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                new ArrayList<TypeInfo>(Arrays.asList(Converter.convertTypes(t.asWildcardType().extendsBounds()))));
478920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
479920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
480920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
481920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    @Override
482920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected Object keyFor(Object o) {
483920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Type t = (Type) o;
484920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String keyString = o.getClass().getName() + "/" + o.toString() + "/";
485920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (t.asParameterizedType() != null) {
486920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        keyString += t.asParameterizedType().toString() + "/";
487920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (t.asParameterizedType().typeArguments() != null) {
488920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          for (Type ty : t.asParameterizedType().typeArguments()) {
489920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            keyString += ty.toString() + "/";
490920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
491920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
492920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
493920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        keyString += "NoParameterizedType//";
494920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
495920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (t.asTypeVariable() != null) {
496920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        keyString += t.asTypeVariable().toString() + "/";
497920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (t.asTypeVariable().bounds() != null) {
498920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          for (Type ty : t.asTypeVariable().bounds()) {
499920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            keyString += ty.toString() + "/";
500920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
501920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
502920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
503920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        keyString += "NoTypeVariable//";
504920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
505920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (t.asWildcardType() != null) {
506920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        keyString += t.asWildcardType().toString() + "/";
507920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (t.asWildcardType().superBounds() != null) {
508920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          for (Type ty : t.asWildcardType().superBounds()) {
509920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            keyString += ty.toString() + "/";
510920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
511920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
512920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (t.asWildcardType().extendsBounds() != null) {
513920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          for (Type ty : t.asWildcardType().extendsBounds()) {
514920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            keyString += ty.toString() + "/";
515920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          }
516920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
517920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
518920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        keyString += "NoWildCardType//";
519920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
520920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
521920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return keyString;
522920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
523920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  };
524920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
525920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static TypeInfo obtainTypeFromString(String type) {
526920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return (TypeInfo) mTypesFromString.obtain(type);
527920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
528920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
529920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static final Cache mTypesFromString = new Cache() {
530920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    @Override
531920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected Object make(Object o) {
532920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String name = (String) o;
533920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return new TypeInfo(name);
534920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
535920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
536920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    @Override
537920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected void made(Object o, Object r) {
538920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
539920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
540920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
541920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    @Override
542920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected Object keyFor(Object o) {
543920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return o;
544920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
545920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  };
546920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
547920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static MemberInfo obtainMember(MemberDoc o) {
548920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return (MemberInfo) mMembers.obtain(o);
549920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
550920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
551920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static Cache mMembers = new Cache() {
552920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    @Override
553920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected Object make(Object o) {
554920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (o instanceof MethodDoc) {
555920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return Converter.obtainMethod((MethodDoc) o);
556920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (o instanceof ConstructorDoc) {
557920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return Converter.obtainMethod((ConstructorDoc) o);
558920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else if (o instanceof FieldDoc) {
559920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return Converter.obtainField((FieldDoc) o);
560920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
561920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return null;
562920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
563920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
564920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  };
565920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
566920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static AnnotationInstanceInfo[] convertAnnotationInstances(AnnotationDesc[] orig) {
567920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int len = orig.length;
568920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    AnnotationInstanceInfo[] out = new AnnotationInstanceInfo[len];
569920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    for (int i = 0; i < len; i++) {
570920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      out[i] = Converter.obtainAnnotationInstance(orig[i]);
571920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
572920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return out;
573920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
574920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
575920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
576920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static AnnotationInstanceInfo obtainAnnotationInstance(AnnotationDesc o) {
577920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return (AnnotationInstanceInfo) mAnnotationInstances.obtain(o);
578920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
579920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
580920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static Cache mAnnotationInstances = new Cache() {
581920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    @Override
582920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected Object make(Object o) {
583920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      AnnotationDesc a = (AnnotationDesc) o;
584920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ClassInfo annotationType = Converter.obtainClass(a.annotationType());
585920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      AnnotationDesc.ElementValuePair[] ev = a.elementValues();
586920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      AnnotationValueInfo[] elementValues = new AnnotationValueInfo[ev.length];
587920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (int i = 0; i < ev.length; i++) {
588920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        elementValues[i] =
589920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            obtainAnnotationValue(ev[i].value(), Converter.obtainMethod(ev[i].element()));
590920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
591920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return new AnnotationInstanceInfo(annotationType, elementValues);
592920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
593920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  };
594920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
595920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
596920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private abstract static class Cache {
597920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    void put(Object key, Object value) {
598920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mCache.put(key, value);
599920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
600920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
601920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Object obtain(Object o) {
602920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (o == null) {
603920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return null;
604920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
605920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Object k = keyFor(o);
606920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      Object r = mCache.get(k);
607920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (r == null) {
608920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        r = make(o);
609920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        mCache.put(k, r);
610920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        made(o, r);
611920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
612920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return r;
613920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
614920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
615920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected HashMap<Object, Object> mCache = new HashMap<Object, Object>();
616920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
617920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected abstract Object make(Object o);
618920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
619920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected void made(Object o, Object r) {}
620920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
621920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    protected Object keyFor(Object o) {
622920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return o;
623920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
624920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
625920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Object[] all() {
626920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return null;
627920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
628920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
629920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
630920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  // annotation values
631920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static HashMap<AnnotationValue, AnnotationValueInfo> mAnnotationValues =
632920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      new HashMap<AnnotationValue, AnnotationValueInfo>();
633920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static HashSet<AnnotationValue> mAnnotationValuesNeedingInit =
634920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      new HashSet<AnnotationValue>();
635920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
636920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static AnnotationValueInfo obtainAnnotationValue(AnnotationValue o, MethodInfo element) {
637920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (o == null) {
638920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return null;
639920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
640920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    AnnotationValueInfo v = mAnnotationValues.get(o);
641920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (v != null) return v;
642920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    v = new AnnotationValueInfo(element);
643920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mAnnotationValues.put(o, v);
644920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mAnnotationValuesNeedingInit != null) {
645920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mAnnotationValuesNeedingInit.add(o);
646920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else {
647920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      initAnnotationValue(o, v);
648920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
649920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return v;
650920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
651920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
652920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void initAnnotationValue(AnnotationValue o, AnnotationValueInfo v) {
653920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Object orig = o.value();
654920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    Object converted;
655920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (orig instanceof Type) {
656920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // class literal
657920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      converted = Converter.obtainType((Type) orig);
658920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else if (orig instanceof FieldDoc) {
659920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // enum constant
660920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      converted = Converter.obtainField((FieldDoc) orig);
661920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else if (orig instanceof AnnotationDesc) {
662920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // annotation instance
663920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      converted = Converter.obtainAnnotationInstance((AnnotationDesc) orig);
664920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else if (orig instanceof AnnotationValue[]) {
665920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      AnnotationValue[] old = (AnnotationValue[]) orig;
666d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      ArrayList<AnnotationValueInfo> values = new ArrayList<AnnotationValueInfo>();
667d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      for (int i = 0; i < old.length; i++) {
668d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        values.add(Converter.obtainAnnotationValue(old[i], null));
669920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
670d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      converted = values;
671920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else {
672920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      converted = orig;
673920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
674920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    v.init(converted);
675920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
676920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
677920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private static void finishAnnotationValueInit() {
678920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int depth = 0;
679920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    while (mAnnotationValuesNeedingInit.size() > 0) {
680920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      HashSet<AnnotationValue> set = mAnnotationValuesNeedingInit;
681920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mAnnotationValuesNeedingInit = new HashSet<AnnotationValue>();
682920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (AnnotationValue o : set) {
683920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        AnnotationValueInfo v = mAnnotationValues.get(o);
684920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        initAnnotationValue(o, v);
685920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
686920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      depth++;
687920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
688920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mAnnotationValuesNeedingInit = null;
689920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
690920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
691