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.google.clearsilver.jsilver.data.Data;
20920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
21920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.*;
22920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
23d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinpublic class TypeInfo implements Resolvable {
24920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public static final Set<String> PRIMITIVE_TYPES = Collections.unmodifiableSet(
25920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      new HashSet<String>(Arrays.asList("boolean", "byte", "char", "double", "float", "int",
26920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      "long", "short", "void")));
27920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
28920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public TypeInfo(boolean isPrimitive, String dimension, String simpleTypeName,
29920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      String qualifiedTypeName, ClassInfo cl) {
30920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mIsPrimitive = isPrimitive;
31920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mDimension = dimension;
32920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mSimpleTypeName = simpleTypeName;
33920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mQualifiedTypeName = qualifiedTypeName;
34920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mClass = cl;
35920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
36920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
37920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public TypeInfo(String typeString) {
38920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // VarArgs
39920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (typeString.endsWith("...")) {
40920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      typeString = typeString.substring(0, typeString.length() - 3);
41920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
42920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
43920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // Generic parameters
44920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int paramStartPos = typeString.indexOf('<');
45920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (paramStartPos > -1) {
46920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      ArrayList<TypeInfo> generics = new ArrayList<TypeInfo>();
47920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      int paramEndPos = typeString.lastIndexOf('>');
48920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
49920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      int entryStartPos = paramStartPos + 1;
50920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      int bracketNesting = 0;
51920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (int i = entryStartPos; i < paramEndPos; i++) {
52920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        char c = typeString.charAt(i);
53920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (c == ',' && bracketNesting == 0) {
54920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          String entry = typeString.substring(entryStartPos, i).trim();
55920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          TypeInfo info = new TypeInfo(entry);
56920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          generics.add(info);
57920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          entryStartPos = i + 1;
58920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        } else if (c == '<') {
59920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          bracketNesting++;
60920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        } else if (c == '>') {
61920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          bracketNesting--;
62920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
63920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
64920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
65920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      TypeInfo info = new TypeInfo(typeString.substring(entryStartPos, paramEndPos).trim());
66920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      generics.add(info);
67920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
68d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      mTypeArguments = generics;
69920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
70920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (paramEndPos < typeString.length() - 1) {
71920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        typeString = typeString.substring(0,paramStartPos) + typeString.substring(paramEndPos + 1);
72920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
73920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        typeString = typeString.substring(0,paramStartPos);
74920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
75920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
76920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
77920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    // Dimensions
78920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    int pos = typeString.indexOf('[');
79920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (pos > -1) {
80920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mDimension = typeString.substring(pos);
81920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      typeString = typeString.substring(0, pos);
82920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else {
83920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mDimension = "";
84920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
85920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
86920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (PRIMITIVE_TYPES.contains(typeString)) {
87920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mIsPrimitive = true;
88920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mSimpleTypeName = typeString;
89920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mQualifiedTypeName = typeString;
90920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else {
91920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      mQualifiedTypeName = typeString;
92920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      pos = typeString.lastIndexOf('.');
93920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (pos > -1) {
94920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        mSimpleTypeName = typeString.substring(pos + 1);
95920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
96920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        mSimpleTypeName = typeString;
97920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
98920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
99920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
100920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
101d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson  /**
102d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson   * Copy Constructor.
103d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson   */
104d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson  private TypeInfo(TypeInfo other) {
105d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    mIsPrimitive = other.isPrimitive();
106d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    mIsTypeVariable = other.isTypeVariable();
107d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    mIsWildcard = other.isWildcard();
108d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    mDimension = other.dimension();
109d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    mSimpleTypeName = other.simpleTypeName();
110d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    mQualifiedTypeName = other.qualifiedTypeName();
111d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    mClass = other.asClassInfo();
112d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    if (other.typeArguments() != null) {
113d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson      mTypeArguments = new ArrayList<TypeInfo>(other.typeArguments());
114d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    }
115d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    if (other.superBounds() != null) {
116d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson      mSuperBounds = new ArrayList<TypeInfo>(other.superBounds());
117d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    }
118d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    if (other.extendsBounds() != null) {
119d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson      mExtendsBounds = new ArrayList<TypeInfo>(other.extendsBounds());
120d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    }
121d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    mFullName = other.fullName();
122d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson  }
123d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson
124920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public ClassInfo asClassInfo() {
125920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mClass;
126920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
127920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
128920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public boolean isPrimitive() {
129920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mIsPrimitive;
130920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
131920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
132920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String dimension() {
133920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mDimension;
134920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
135920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
1366ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein  public void setDimension(String dimension) {
1376ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      mDimension = dimension;
1386ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein  }
1396ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein
140920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String simpleTypeName() {
141920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mSimpleTypeName;
142920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
143920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
144920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String qualifiedTypeName() {
145920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mQualifiedTypeName;
146920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
147920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
148920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String fullName() {
149920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mFullName != null) {
150920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return mFullName;
151920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else {
152920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return fullName(new HashSet<String>());
153920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
154920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
155920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
156d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  public static String typeArgumentsName(ArrayList<TypeInfo> args, HashSet<String> typeVars) {
157920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String result = "<";
158d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
159d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    int i = 0;
160d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    for (TypeInfo arg : args) {
161d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      result += arg.fullName(typeVars);
162d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      if (i != (args.size()-1)) {
163920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        result += ", ";
164920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
165d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      i++;
166920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
167920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    result += ">";
168920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return result;
169920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
170920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
171920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String fullName(HashSet<String> typeVars) {
172920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mFullName = fullNameNoDimension(typeVars) + mDimension;
173920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mFullName;
174920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
175920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
176434521c12e31824372d1d25ea2020fb250585264Florian Uunk  public String fullNameNoBounds(HashSet<String> typeVars) {
177434521c12e31824372d1d25ea2020fb250585264Florian Uunk    return fullNameNoDimensionNoBounds(typeVars) + mDimension;
178434521c12e31824372d1d25ea2020fb250585264Florian Uunk  }
179434521c12e31824372d1d25ea2020fb250585264Florian Uunk
180434521c12e31824372d1d25ea2020fb250585264Florian Uunk  // don't recurse forever with the parameters. This handles
181434521c12e31824372d1d25ea2020fb250585264Florian Uunk  // Enum<K extends Enum<K>>
182434521c12e31824372d1d25ea2020fb250585264Florian Uunk  private boolean checkRecurringTypeVar(HashSet<String> typeVars) {
183920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mIsTypeVariable) {
184920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (typeVars.contains(mQualifiedTypeName)) {
185434521c12e31824372d1d25ea2020fb250585264Florian Uunk        return true;
186920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
187920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      typeVars.add(mQualifiedTypeName);
188920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
189434521c12e31824372d1d25ea2020fb250585264Florian Uunk    return false;
190434521c12e31824372d1d25ea2020fb250585264Florian Uunk  }
191434521c12e31824372d1d25ea2020fb250585264Florian Uunk
192434521c12e31824372d1d25ea2020fb250585264Florian Uunk  private String fullNameNoDimensionNoBounds(HashSet<String> typeVars) {
193434521c12e31824372d1d25ea2020fb250585264Florian Uunk    String fullName = null;
194434521c12e31824372d1d25ea2020fb250585264Florian Uunk    if (checkRecurringTypeVar(typeVars)) {
195434521c12e31824372d1d25ea2020fb250585264Florian Uunk      return mQualifiedTypeName;
196434521c12e31824372d1d25ea2020fb250585264Florian Uunk    }
197920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    /*
198920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson     * if (fullName != null) { return fullName; }
199920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson     */
200920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    fullName = mQualifiedTypeName;
201d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    if (mTypeArguments != null && !mTypeArguments.isEmpty()) {
202920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      fullName += typeArgumentsName(mTypeArguments, typeVars);
203434521c12e31824372d1d25ea2020fb250585264Florian Uunk    }
204434521c12e31824372d1d25ea2020fb250585264Florian Uunk    return fullName;
205434521c12e31824372d1d25ea2020fb250585264Florian Uunk  }
206434521c12e31824372d1d25ea2020fb250585264Florian Uunk
207434521c12e31824372d1d25ea2020fb250585264Florian Uunk  public String fullNameNoDimension(HashSet<String> typeVars) {
208434521c12e31824372d1d25ea2020fb250585264Florian Uunk    String fullName = null;
209434521c12e31824372d1d25ea2020fb250585264Florian Uunk    if (checkRecurringTypeVar(typeVars)) {
210434521c12e31824372d1d25ea2020fb250585264Florian Uunk      return mQualifiedTypeName;
211434521c12e31824372d1d25ea2020fb250585264Florian Uunk    }
212434521c12e31824372d1d25ea2020fb250585264Florian Uunk    fullName = fullNameNoDimensionNoBounds(typeVars);
213434521c12e31824372d1d25ea2020fb250585264Florian Uunk    if (mTypeArguments == null || mTypeArguments.isEmpty()) {
214434521c12e31824372d1d25ea2020fb250585264Florian Uunk       if (mSuperBounds != null && !mSuperBounds.isEmpty()) {
215d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        for (TypeInfo superBound : mSuperBounds) {
216d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            if (superBound == mSuperBounds.get(0)) {
217434521c12e31824372d1d25ea2020fb250585264Florian Uunk                fullName += " super " + superBound.fullNameNoBounds(typeVars);
218d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            } else {
219434521c12e31824372d1d25ea2020fb250585264Florian Uunk                fullName += " & " + superBound.fullNameNoBounds(typeVars);
220d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            }
221d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        }
222434521c12e31824372d1d25ea2020fb250585264Florian Uunk      } else if (mExtendsBounds != null && !mExtendsBounds.isEmpty()) {
223d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        for (TypeInfo extendsBound : mExtendsBounds) {
224d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            if (extendsBound == mExtendsBounds.get(0)) {
225434521c12e31824372d1d25ea2020fb250585264Florian Uunk                fullName += " extends " + extendsBound.fullNameNoBounds(typeVars);
226d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            } else {
227434521c12e31824372d1d25ea2020fb250585264Florian Uunk                fullName += " & " + extendsBound.fullNameNoBounds(typeVars);
228d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            }
229d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        }
230434521c12e31824372d1d25ea2020fb250585264Florian Uunk      }
231920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
232920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return fullName;
233920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
234920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
235d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  public ArrayList<TypeInfo> typeArguments() {
236920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mTypeArguments;
237920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
238920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
239920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public void makeHDF(Data data, String base) {
240920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeHDFRecursive(data, base, false, false, new HashSet<String>());
241920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
242920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
243920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public void makeQualifiedHDF(Data data, String base) {
244920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeHDFRecursive(data, base, true, false, new HashSet<String>());
245920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
246920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
247920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public void makeHDF(Data data, String base, boolean isLastVararg, HashSet<String> typeVariables) {
248920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeHDFRecursive(data, base, false, isLastVararg, typeVariables);
249920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
250920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
251920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public void makeQualifiedHDF(Data data, String base, HashSet<String> typeVariables) {
252920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeHDFRecursive(data, base, true, false, typeVariables);
253920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
254920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
255920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private void makeHDFRecursive(Data data, String base, boolean qualified, boolean isLastVararg,
256920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      HashSet<String> typeVars) {
257920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String label = qualified ? qualifiedTypeName() : simpleTypeName();
258920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    label += (isLastVararg) ? "..." : dimension();
259920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    data.setValue(base + ".label", label);
260920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mIsTypeVariable || mIsWildcard) {
261920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // could link to an @param tag on the class to describe this
262920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      // but for now, just don't make it a link
263920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else if (!isPrimitive() && mClass != null) {
264920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (mClass.isIncluded()) {
265920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        data.setValue(base + ".link", mClass.htmlPage());
266920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        data.setValue(base + ".since", mClass.getSince());
267920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
2689c584846aff32976d94246c7682a980346d12f44Jeff Hamilton        Doclava.federationTagger.tag(mClass);
269920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        if (!mClass.getFederatedReferences().isEmpty()) {
270920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          FederatedSite site = mClass.getFederatedReferences().iterator().next();
271920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          data.setValue(base + ".link", site.linkFor(mClass.htmlPage()));
272920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson          data.setValue(base + ".federated", site.name());
273920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        }
274920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
275920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
276920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
277920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mIsTypeVariable) {
278920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if (typeVars.contains(qualifiedTypeName())) {
279920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // don't recurse forever with the parameters. This handles
280920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        // Enum<K extends Enum<K>>
281920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return;
282920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
283920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      typeVars.add(qualifiedTypeName());
284920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
285920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mTypeArguments != null) {
286920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      TypeInfo.makeHDF(data, base + ".typeArguments", mTypeArguments, qualified, typeVars);
287920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
288920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mSuperBounds != null) {
289920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      TypeInfo.makeHDF(data, base + ".superBounds", mSuperBounds, qualified, typeVars);
290920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
291920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mExtendsBounds != null) {
292920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      TypeInfo.makeHDF(data, base + ".extendsBounds", mExtendsBounds, qualified, typeVars);
293920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
294920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
295920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
296d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  public static void makeHDF(Data data, String base, ArrayList<TypeInfo> types, boolean qualified,
297920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      HashSet<String> typeVariables) {
298d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    int i = 0;
299d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    for (TypeInfo type : types) {
300d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      type.makeHDFRecursive(data, base + "." + i++, qualified, false, typeVariables);
301920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
302920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
303920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
304d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  public static void makeHDF(Data data, String base, ArrayList<TypeInfo> types, boolean qualified) {
305920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    makeHDF(data, base, types, qualified, new HashSet<String>());
306920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
307920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
308d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  void setTypeArguments(ArrayList<TypeInfo> args) {
309920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mTypeArguments = args;
310920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
311920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
312d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  public void addTypeArgument(TypeInfo arg) {
313d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      if (mTypeArguments == null) {
314d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein          mTypeArguments = new ArrayList<TypeInfo>();
315d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      }
316d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
317d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      mTypeArguments.add(arg);
318d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  }
319d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
320d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  void setBounds(ArrayList<TypeInfo> superBounds, ArrayList<TypeInfo> extendsBounds) {
321920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mSuperBounds = superBounds;
322920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mExtendsBounds = extendsBounds;
323920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
324920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
325d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  public ArrayList<TypeInfo> superBounds() {
326d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      return mSuperBounds;
327d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  }
328d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
329d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  public ArrayList<TypeInfo> extendsBounds() {
330d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      return mExtendsBounds;
331d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  }
332d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
333920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  void setIsTypeVariable(boolean b) {
334920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mIsTypeVariable = b;
335920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
336920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
337920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  void setIsWildcard(boolean b) {
338920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    mIsWildcard = b;
339920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
340920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
3416ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein  public boolean isWildcard() {
3426ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      return mIsWildcard;
3436ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein  }
3446ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein
345d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  static HashSet<String> typeVariables(ArrayList<TypeInfo> params) {
3469ccd9e3a9df835dc134e7edd2e4236220aed401eBen Dodson    return typeVariables(params, new HashSet<String>());
347920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
348920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
349d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  static HashSet<String> typeVariables(ArrayList<TypeInfo> params, HashSet<String> result) {
350d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein    if (params != null) {
351d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        for (TypeInfo t : params) {
352d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            if (t.mIsTypeVariable) {
353d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein                result.add(t.mQualifiedTypeName);
354d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein            }
355d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein        }
356920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
357920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return result;
358920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
359920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
360920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
361920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public boolean isTypeVariable() {
362920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return mIsTypeVariable;
363920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
364920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
365920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String defaultValue() {
366920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mIsPrimitive) {
367920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      if ("boolean".equals(mSimpleTypeName)) {
368920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return "false";
369920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      } else {
370920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        return "0";
371920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
372920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    } else {
373920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      return "null";
374920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
375920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
376920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
377920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  @Override
378920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  public String toString() {
379920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    String returnString = "";
380920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    returnString +=
381920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        "Primitive?: " + mIsPrimitive + " TypeVariable?: " + mIsTypeVariable + " Wildcard?: "
382920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            + mIsWildcard + " Dimension: " + mDimension + " QualifedTypeName: "
383920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson            + mQualifiedTypeName;
384920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
385920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mTypeArguments != null) {
386920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      returnString += "\nTypeArguments: ";
387920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (TypeInfo tA : mTypeArguments) {
388920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        returnString += tA.qualifiedTypeName() + "(" + tA + ") ";
389920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
390920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
391920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mSuperBounds != null) {
392920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      returnString += "\nSuperBounds: ";
393920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (TypeInfo tA : mSuperBounds) {
394920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        returnString += tA.qualifiedTypeName() + "(" + tA + ") ";
395920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
396920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
397920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    if (mExtendsBounds != null) {
398920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      returnString += "\nExtendsBounds: ";
399920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      for (TypeInfo tA : mExtendsBounds) {
400920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson        returnString += tA.qualifiedTypeName() + "(" + tA + ") ";
401920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson      }
402920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    }
403920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson    return returnString;
404920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  }
405920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson
406d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  public void addResolution(Resolution resolution) {
407d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      if (mResolutions == null) {
408d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein          mResolutions = new ArrayList<Resolution>();
409d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      }
410d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
411d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      mResolutions.add(resolution);
412d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  }
413d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
414d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  public void printResolutions() {
4156ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      if (mResolutions == null || mResolutions.isEmpty()) {
4166ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein          return;
4176ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      }
4186ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein
419d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      System.out.println("Resolutions for Type " + mSimpleTypeName + ":");
420d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      for (Resolution r : mResolutions) {
421d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein          System.out.println(r);
422d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      }
423d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  }
424d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
4256ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein  public boolean resolveResolutions() {
4266ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      ArrayList<Resolution> resolutions = mResolutions;
4276ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      mResolutions = new ArrayList<Resolution>();
4286ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein
4296ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      boolean allResolved = true;
4306ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      for (Resolution resolution : resolutions) {
4316ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein          if ("class".equals(resolution.getVariable())) {
4326ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein              StringBuilder qualifiedClassName = new StringBuilder();
4336ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein              InfoBuilder.resolveQualifiedName(resolution.getValue(), qualifiedClassName,
4346ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein                      resolution.getInfoBuilder());
4356ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein
4366ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein              // if we still couldn't resolve it, save it for the next pass
4376ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein              if ("".equals(qualifiedClassName.toString())) {
4386ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein                  mResolutions.add(resolution);
4396ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein                  allResolved = false;
4406ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein              } else {
4416ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein                  mClass = InfoBuilder.Caches.obtainClass(qualifiedClassName.toString());
4426ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein              }
4436ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein          }
4446ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      }
4456ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein
4466ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein      return allResolved;
4476ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein  }
4486ba612efffba42bec102ac58a1540496158f747eAndrew Sapperstein
449d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson  /**
450d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson   * Copy this TypeInfo, but replace type arguments with those defined in the
451d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson   * typeArguments mapping.
452d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson   * <p>
453d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson   * If the current type is one of the base types in the mapping (i.e. a parameter itself)
454d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson   * then this returns the mapped type.
455d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson   */
456d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson  public TypeInfo getTypeWithArguments(Map<String, TypeInfo> typeArguments) {
457d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    if (typeArguments.containsKey(fullName())) {
458d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson      return typeArguments.get(fullName());
459d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    }
460d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson
461d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    TypeInfo ti = new TypeInfo(this);
462d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    if (typeArguments() != null) {
463d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson      ArrayList<TypeInfo> newArgs = new ArrayList<TypeInfo>();
464d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson      for (TypeInfo t : typeArguments()) {
465d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson        newArgs.add(t.getTypeWithArguments(typeArguments));
466d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson      }
467d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson      ti.setTypeArguments(newArgs);
468d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    }
469d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    return ti;
470d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson  }
471d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson
472d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson  /**
473d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson   * Given two TypeInfos that reference the same type, take the first one's type parameters
474d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson   * and generate a mapping from their names to the type parameters defined in the second.
475d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson   */
476d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson  public static Map<String, TypeInfo> getTypeArgumentMapping(TypeInfo generic, TypeInfo typed) {
477d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    Map<String, TypeInfo> map = new HashMap<String, TypeInfo>();
478d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    for (int i = 0; i < generic.typeArguments().size(); i++) {
479d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson      if (typed.typeArguments() != null && typed.typeArguments().size() > i) {
480d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson        map.put(generic.typeArguments().get(i).fullName(), typed.typeArguments().get(i));
481d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson      }
482d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    }
483d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    return map;
484d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson  }
485d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson
486d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson  /**
487d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson   * Given a ClassInfo and a parameterized TypeInfo, take the class's raw type's type parameters
488d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson   * and generate a mapping from their names to the type parameters defined in the TypeInfo.
489d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson   */
490d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson  public static Map<String, TypeInfo> getTypeArgumentMapping(ClassInfo cls, TypeInfo typed) {
491d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson    return getTypeArgumentMapping(cls.asTypeInfo(), typed);
492d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson  }
493d6570b0b7f66519ba50c18d9e08db423bdf1341eJeff Arneson
494d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  private ArrayList<Resolution> mResolutions;
495d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
496920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private boolean mIsPrimitive;
497920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private boolean mIsTypeVariable;
498920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private boolean mIsWildcard;
499920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private String mDimension;
500920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private String mSimpleTypeName;
501920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private String mQualifiedTypeName;
502920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private ClassInfo mClass;
503d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  private ArrayList<TypeInfo> mTypeArguments;
504d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  private ArrayList<TypeInfo> mSuperBounds;
505d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein  private ArrayList<TypeInfo> mExtendsBounds;
506920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson  private String mFullName;
507920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}
508