1/* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.tools.javadoc.main; 27 28import com.sun.javadoc.*; 29import com.sun.tools.javac.code.Symbol; 30import com.sun.tools.javac.code.Symbol.ClassSymbol; 31import com.sun.tools.javac.code.Symbol.CompletionFailure; 32import com.sun.tools.javac.code.Type; 33import com.sun.tools.javac.code.Type.ArrayType; 34import com.sun.tools.javac.code.Type.ClassType; 35import com.sun.tools.javac.code.Type.TypeVar; 36import com.sun.tools.javac.util.List; 37import static com.sun.tools.javac.code.TypeTag.ARRAY; 38 39/** 40 * <p><b>This is NOT part of any supported API. 41 * If you write code that depends on this, you do so at your own risk. 42 * This code and its internal interfaces are subject to change or 43 * deletion without notice.</b> 44 */ 45@Deprecated 46public class TypeMaker { 47 48 public static com.sun.javadoc.Type getType(DocEnv env, Type t) { 49 return getType(env, t, true); 50 } 51 52 /** 53 * @param errToClassDoc if true, ERROR type results in a ClassDoc; 54 * false preserves legacy behavior 55 */ 56 public static com.sun.javadoc.Type getType(DocEnv env, Type t, 57 boolean errorToClassDoc) { 58 return getType(env, t, errorToClassDoc, true); 59 } 60 61 public static com.sun.javadoc.Type getType(DocEnv env, Type t, 62 boolean errToClassDoc, boolean considerAnnotations) { 63 try { 64 return getTypeImpl(env, t, errToClassDoc, considerAnnotations); 65 } catch (CompletionFailure cf) { 66 /* Quietly ignore completion failures and try again - the type 67 * for which the CompletionFailure was thrown shouldn't be completed 68 * again by the completer that threw the CompletionFailure. 69 */ 70 return getType(env, t, errToClassDoc, considerAnnotations); 71 } 72 } 73 74 @SuppressWarnings("fallthrough") 75 private static com.sun.javadoc.Type getTypeImpl(DocEnv env, Type t, 76 boolean errToClassDoc, boolean considerAnnotations) { 77 if (env.legacyDoclet) { 78 t = env.types.erasure(t); 79 } 80 81 if (considerAnnotations && t.isAnnotated()) { 82 return new AnnotatedTypeImpl(env, t); 83 } 84 85 switch (t.getTag()) { 86 case CLASS: 87 if (ClassDocImpl.isGeneric((ClassSymbol)t.tsym)) { 88 return env.getParameterizedType((ClassType)t); 89 } else { 90 return env.getClassDoc((ClassSymbol)t.tsym); 91 } 92 case WILDCARD: 93 Type.WildcardType a = (Type.WildcardType)t; 94 return new WildcardTypeImpl(env, a); 95 case TYPEVAR: return new TypeVariableImpl(env, (TypeVar)t); 96 case ARRAY: return new ArrayTypeImpl(env, t); 97 case BYTE: return PrimitiveType.byteType; 98 case CHAR: return PrimitiveType.charType; 99 case SHORT: return PrimitiveType.shortType; 100 case INT: return PrimitiveType.intType; 101 case LONG: return PrimitiveType.longType; 102 case FLOAT: return PrimitiveType.floatType; 103 case DOUBLE: return PrimitiveType.doubleType; 104 case BOOLEAN: return PrimitiveType.booleanType; 105 case VOID: return PrimitiveType.voidType; 106 case ERROR: 107 if (errToClassDoc) 108 return env.getClassDoc((ClassSymbol)t.tsym); 109 // FALLTHRU 110 default: 111 return new PrimitiveType(t.tsym.getQualifiedName().toString()); 112 } 113 } 114 115 /** 116 * Convert a list of javac types into an array of javadoc types. 117 */ 118 public static com.sun.javadoc.Type[] getTypes(DocEnv env, List<Type> ts) { 119 return getTypes(env, ts, new com.sun.javadoc.Type[ts.length()]); 120 } 121 122 /** 123 * Like the above version, but use and return the array given. 124 */ 125 public static com.sun.javadoc.Type[] getTypes(DocEnv env, List<Type> ts, 126 com.sun.javadoc.Type res[]) { 127 int i = 0; 128 for (Type t : ts) { 129 res[i++] = getType(env, t); 130 } 131 return res; 132 } 133 134 public static String getTypeName(Type t, boolean full) { 135 switch (t.getTag()) { 136 case ARRAY: 137 StringBuilder s = new StringBuilder(); 138 while (t.hasTag(ARRAY)) { 139 s.append("[]"); 140 t = ((ArrayType)t).elemtype; 141 } 142 s.insert(0, getTypeName(t, full)); 143 return s.toString(); 144 case CLASS: 145 return ClassDocImpl.getClassName((ClassSymbol)t.tsym, full); 146 default: 147 return t.tsym.getQualifiedName().toString(); 148 } 149 } 150 151 /** 152 * Return the string representation of a type use. Bounds of type 153 * variables are not included; bounds of wildcard types are. 154 * Class names are qualified if "full" is true. 155 */ 156 static String getTypeString(DocEnv env, Type t, boolean full) { 157 // TODO: should annotations be included here? 158 switch (t.getTag()) { 159 case ARRAY: 160 StringBuilder s = new StringBuilder(); 161 while (t.hasTag(ARRAY)) { 162 s.append("[]"); 163 t = env.types.elemtype(t); 164 } 165 s.insert(0, getTypeString(env, t, full)); 166 return s.toString(); 167 case CLASS: 168 return ParameterizedTypeImpl. 169 parameterizedTypeToString(env, (ClassType)t, full); 170 case WILDCARD: 171 Type.WildcardType a = (Type.WildcardType)t; 172 return WildcardTypeImpl.wildcardTypeToString(env, a, full); 173 default: 174 return t.tsym.getQualifiedName().toString(); 175 } 176 } 177 178 /** 179 * Return the formal type parameters of a class or method as an 180 * angle-bracketed string. Each parameter is a type variable with 181 * optional bounds. Class names are qualified if "full" is true. 182 * Return "" if there are no type parameters or we're hiding generics. 183 */ 184 static String typeParametersString(DocEnv env, Symbol sym, boolean full) { 185 if (env.legacyDoclet || sym.type.getTypeArguments().isEmpty()) { 186 return ""; 187 } 188 StringBuilder s = new StringBuilder(); 189 for (Type t : sym.type.getTypeArguments()) { 190 s.append(s.length() == 0 ? "<" : ", "); 191 s.append(TypeVariableImpl.typeVarToString(env, (TypeVar)t, full)); 192 } 193 s.append(">"); 194 return s.toString(); 195 } 196 197 /** 198 * Return the actual type arguments of a parameterized type as an 199 * angle-bracketed string. Class name are qualified if "full" is true. 200 * Return "" if there are no type arguments or we're hiding generics. 201 */ 202 static String typeArgumentsString(DocEnv env, ClassType cl, boolean full) { 203 if (env.legacyDoclet || cl.getTypeArguments().isEmpty()) { 204 return ""; 205 } 206 StringBuilder s = new StringBuilder(); 207 for (Type t : cl.getTypeArguments()) { 208 s.append(s.length() == 0 ? "<" : ", "); 209 s.append(getTypeString(env, t, full)); 210 } 211 s.append(">"); 212 return s.toString(); 213 } 214 215 216 private static class ArrayTypeImpl implements com.sun.javadoc.Type { 217 218 Type arrayType; 219 220 DocEnv env; 221 222 ArrayTypeImpl(DocEnv env, Type arrayType) { 223 this.env = env; 224 this.arrayType = arrayType; 225 } 226 227 private com.sun.javadoc.Type skipArraysCache = null; 228 229 public com.sun.javadoc.Type getElementType() { 230 return TypeMaker.getType(env, env.types.elemtype(arrayType)); 231 } 232 233 private com.sun.javadoc.Type skipArrays() { 234 if (skipArraysCache == null) { 235 Type t; 236 for (t = arrayType; t.hasTag(ARRAY); t = env.types.elemtype(t)) { } 237 skipArraysCache = TypeMaker.getType(env, t); 238 } 239 return skipArraysCache; 240 } 241 242 /** 243 * Return the type's dimension information, as a string. 244 * <p> 245 * For example, a two dimensional array of String returns '[][]'. 246 */ 247 public String dimension() { 248 StringBuilder dimension = new StringBuilder(); 249 for (Type t = arrayType; t.hasTag(ARRAY); t = env.types.elemtype(t)) { 250 dimension.append("[]"); 251 } 252 return dimension.toString(); 253 } 254 255 /** 256 * Return unqualified name of type excluding any dimension information. 257 * <p> 258 * For example, a two dimensional array of String returns 'String'. 259 */ 260 public String typeName() { 261 return skipArrays().typeName(); 262 } 263 264 /** 265 * Return qualified name of type excluding any dimension information. 266 *<p> 267 * For example, a two dimensional array of String 268 * returns 'java.lang.String'. 269 */ 270 public String qualifiedTypeName() { 271 return skipArrays().qualifiedTypeName(); 272 } 273 274 /** 275 * Return the simple name of this type excluding any dimension information. 276 */ 277 public String simpleTypeName() { 278 return skipArrays().simpleTypeName(); 279 } 280 281 /** 282 * Return this type as a class. Array dimensions are ignored. 283 * 284 * @return a ClassDocImpl if the type is a Class. 285 * Return null if it is a primitive type.. 286 */ 287 public ClassDoc asClassDoc() { 288 return skipArrays().asClassDoc(); 289 } 290 291 /** 292 * Return this type as a <code>ParameterizedType</code> if it 293 * represents a parameterized type. Array dimensions are ignored. 294 */ 295 public ParameterizedType asParameterizedType() { 296 return skipArrays().asParameterizedType(); 297 } 298 299 /** 300 * Return this type as a <code>TypeVariable</code> if it represents 301 * a type variable. Array dimensions are ignored. 302 */ 303 public TypeVariable asTypeVariable() { 304 return skipArrays().asTypeVariable(); 305 } 306 307 /** 308 * Return null, as there are no arrays of wildcard types. 309 */ 310 public WildcardType asWildcardType() { 311 return null; 312 } 313 314 /** 315 * Return null, as there are no annotations of the type 316 */ 317 public AnnotatedType asAnnotatedType() { 318 return null; 319 } 320 321 /** 322 * Return this type as an <code>AnnotationTypeDoc</code> if it 323 * represents an annotation type. Array dimensions are ignored. 324 */ 325 public AnnotationTypeDoc asAnnotationTypeDoc() { 326 return skipArrays().asAnnotationTypeDoc(); 327 } 328 329 /** 330 * Return true if this is an array of a primitive type. 331 */ 332 public boolean isPrimitive() { 333 return skipArrays().isPrimitive(); 334 } 335 336 /** 337 * Return a string representation of the type. 338 * 339 * Return name of type including any dimension information. 340 * <p> 341 * For example, a two dimensional array of String returns 342 * <code>String[][]</code>. 343 * 344 * @return name of type including any dimension information. 345 */ 346 @Override 347 public String toString() { 348 return qualifiedTypeName() + dimension(); 349 } 350 } 351} 352