Thu, 24 May 2018 16:48:51 +0800
Merge
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 */
26 package com.sun.tools.javadoc;
28 import com.sun.javadoc.*;
29 import com.sun.tools.javac.code.Symbol;
30 import com.sun.tools.javac.code.Symbol.ClassSymbol;
31 import com.sun.tools.javac.code.Symbol.CompletionFailure;
32 import com.sun.tools.javac.code.Type;
33 import com.sun.tools.javac.code.Type.ArrayType;
34 import com.sun.tools.javac.code.Type.ClassType;
35 import com.sun.tools.javac.code.Type.TypeVar;
36 import com.sun.tools.javac.util.List;
37 import static com.sun.tools.javac.code.TypeTag.ARRAY;
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 public class TypeMaker {
47 public static com.sun.javadoc.Type getType(DocEnv env, Type t) {
48 return getType(env, t, true);
49 }
51 /**
52 * @param errToClassDoc if true, ERROR type results in a ClassDoc;
53 * false preserves legacy behavior
54 */
55 public static com.sun.javadoc.Type getType(DocEnv env, Type t,
56 boolean errorToClassDoc) {
57 return getType(env, t, errorToClassDoc, true);
58 }
60 public static com.sun.javadoc.Type getType(DocEnv env, Type t,
61 boolean errToClassDoc, boolean considerAnnotations) {
62 try {
63 return getTypeImpl(env, t, errToClassDoc, considerAnnotations);
64 } catch (CompletionFailure cf) {
65 /* Quietly ignore completion failures and try again - the type
66 * for which the CompletionFailure was thrown shouldn't be completed
67 * again by the completer that threw the CompletionFailure.
68 */
69 return getType(env, t, errToClassDoc, considerAnnotations);
70 }
71 }
73 @SuppressWarnings("fallthrough")
74 private static com.sun.javadoc.Type getTypeImpl(DocEnv env, Type t,
75 boolean errToClassDoc, boolean considerAnnotations) {
76 if (env.legacyDoclet) {
77 t = env.types.erasure(t);
78 }
80 if (considerAnnotations && t.isAnnotated()) {
81 return new AnnotatedTypeImpl(env, t);
82 }
84 switch (t.getTag()) {
85 case CLASS:
86 if (ClassDocImpl.isGeneric((ClassSymbol)t.tsym)) {
87 return env.getParameterizedType((ClassType)t);
88 } else {
89 return env.getClassDoc((ClassSymbol)t.tsym);
90 }
91 case WILDCARD:
92 Type.WildcardType a = (Type.WildcardType)t;
93 return new WildcardTypeImpl(env, a);
94 case TYPEVAR: return new TypeVariableImpl(env, (TypeVar)t);
95 case ARRAY: return new ArrayTypeImpl(env, t);
96 case BYTE: return PrimitiveType.byteType;
97 case CHAR: return PrimitiveType.charType;
98 case SHORT: return PrimitiveType.shortType;
99 case INT: return PrimitiveType.intType;
100 case LONG: return PrimitiveType.longType;
101 case FLOAT: return PrimitiveType.floatType;
102 case DOUBLE: return PrimitiveType.doubleType;
103 case BOOLEAN: return PrimitiveType.booleanType;
104 case VOID: return PrimitiveType.voidType;
105 case ERROR:
106 if (errToClassDoc)
107 return env.getClassDoc((ClassSymbol)t.tsym);
108 // FALLTHRU
109 default:
110 return new PrimitiveType(t.tsym.getQualifiedName().toString());
111 }
112 }
114 /**
115 * Convert a list of javac types into an array of javadoc types.
116 */
117 public static com.sun.javadoc.Type[] getTypes(DocEnv env, List<Type> ts) {
118 return getTypes(env, ts, new com.sun.javadoc.Type[ts.length()]);
119 }
121 /**
122 * Like the above version, but use and return the array given.
123 */
124 public static com.sun.javadoc.Type[] getTypes(DocEnv env, List<Type> ts,
125 com.sun.javadoc.Type res[]) {
126 int i = 0;
127 for (Type t : ts) {
128 res[i++] = getType(env, t);
129 }
130 return res;
131 }
133 public static String getTypeName(Type t, boolean full) {
134 switch (t.getTag()) {
135 case ARRAY:
136 StringBuilder s = new StringBuilder();
137 while (t.hasTag(ARRAY)) {
138 s.append("[]");
139 t = ((ArrayType)t).elemtype;
140 }
141 s.insert(0, getTypeName(t, full));
142 return s.toString();
143 case CLASS:
144 return ClassDocImpl.getClassName((ClassSymbol)t.tsym, full);
145 default:
146 return t.tsym.getQualifiedName().toString();
147 }
148 }
150 /**
151 * Return the string representation of a type use. Bounds of type
152 * variables are not included; bounds of wildcard types are.
153 * Class names are qualified if "full" is true.
154 */
155 static String getTypeString(DocEnv env, Type t, boolean full) {
156 // TODO: should annotations be included here?
157 if (t.isAnnotated()) {
158 t = t.unannotatedType();
159 }
160 switch (t.getTag()) {
161 case ARRAY:
162 StringBuilder s = new StringBuilder();
163 while (t.hasTag(ARRAY)) {
164 s.append("[]");
165 t = env.types.elemtype(t);
166 }
167 s.insert(0, getTypeString(env, t, full));
168 return s.toString();
169 case CLASS:
170 return ParameterizedTypeImpl.
171 parameterizedTypeToString(env, (ClassType)t, full);
172 case WILDCARD:
173 Type.WildcardType a = (Type.WildcardType)t;
174 return WildcardTypeImpl.wildcardTypeToString(env, a, full);
175 default:
176 return t.tsym.getQualifiedName().toString();
177 }
178 }
180 /**
181 * Return the formal type parameters of a class or method as an
182 * angle-bracketed string. Each parameter is a type variable with
183 * optional bounds. Class names are qualified if "full" is true.
184 * Return "" if there are no type parameters or we're hiding generics.
185 */
186 static String typeParametersString(DocEnv env, Symbol sym, boolean full) {
187 if (env.legacyDoclet || sym.type.getTypeArguments().isEmpty()) {
188 return "";
189 }
190 StringBuilder s = new StringBuilder();
191 for (Type t : sym.type.getTypeArguments()) {
192 s.append(s.length() == 0 ? "<" : ", ");
193 s.append(TypeVariableImpl.typeVarToString(env, (TypeVar)t, full));
194 }
195 s.append(">");
196 return s.toString();
197 }
199 /**
200 * Return the actual type arguments of a parameterized type as an
201 * angle-bracketed string. Class name are qualified if "full" is true.
202 * Return "" if there are no type arguments or we're hiding generics.
203 */
204 static String typeArgumentsString(DocEnv env, ClassType cl, boolean full) {
205 if (env.legacyDoclet || cl.getTypeArguments().isEmpty()) {
206 return "";
207 }
208 StringBuilder s = new StringBuilder();
209 for (Type t : cl.getTypeArguments()) {
210 s.append(s.length() == 0 ? "<" : ", ");
211 s.append(getTypeString(env, t, full));
212 }
213 s.append(">");
214 return s.toString();
215 }
218 private static class ArrayTypeImpl implements com.sun.javadoc.Type {
220 Type arrayType;
222 DocEnv env;
224 ArrayTypeImpl(DocEnv env, Type arrayType) {
225 this.env = env;
226 this.arrayType = arrayType;
227 }
229 private com.sun.javadoc.Type skipArraysCache = null;
231 public com.sun.javadoc.Type getElementType() {
232 return TypeMaker.getType(env, env.types.elemtype(arrayType));
233 }
235 private com.sun.javadoc.Type skipArrays() {
236 if (skipArraysCache == null) {
237 Type t;
238 for (t = arrayType; t.hasTag(ARRAY); t = env.types.elemtype(t)) { }
239 skipArraysCache = TypeMaker.getType(env, t);
240 }
241 return skipArraysCache;
242 }
244 /**
245 * Return the type's dimension information, as a string.
246 * <p>
247 * For example, a two dimensional array of String returns '[][]'.
248 */
249 public String dimension() {
250 StringBuilder dimension = new StringBuilder();
251 for (Type t = arrayType; t.hasTag(ARRAY); t = env.types.elemtype(t)) {
252 dimension.append("[]");
253 }
254 return dimension.toString();
255 }
257 /**
258 * Return unqualified name of type excluding any dimension information.
259 * <p>
260 * For example, a two dimensional array of String returns 'String'.
261 */
262 public String typeName() {
263 return skipArrays().typeName();
264 }
266 /**
267 * Return qualified name of type excluding any dimension information.
268 *<p>
269 * For example, a two dimensional array of String
270 * returns 'java.lang.String'.
271 */
272 public String qualifiedTypeName() {
273 return skipArrays().qualifiedTypeName();
274 }
276 /**
277 * Return the simple name of this type excluding any dimension information.
278 */
279 public String simpleTypeName() {
280 return skipArrays().simpleTypeName();
281 }
283 /**
284 * Return this type as a class. Array dimensions are ignored.
285 *
286 * @return a ClassDocImpl if the type is a Class.
287 * Return null if it is a primitive type..
288 */
289 public ClassDoc asClassDoc() {
290 return skipArrays().asClassDoc();
291 }
293 /**
294 * Return this type as a <code>ParameterizedType</code> if it
295 * represents a parameterized type. Array dimensions are ignored.
296 */
297 public ParameterizedType asParameterizedType() {
298 return skipArrays().asParameterizedType();
299 }
301 /**
302 * Return this type as a <code>TypeVariable</code> if it represents
303 * a type variable. Array dimensions are ignored.
304 */
305 public TypeVariable asTypeVariable() {
306 return skipArrays().asTypeVariable();
307 }
309 /**
310 * Return null, as there are no arrays of wildcard types.
311 */
312 public WildcardType asWildcardType() {
313 return null;
314 }
316 /**
317 * Return null, as there are no annotations of the type
318 */
319 public AnnotatedType asAnnotatedType() {
320 return null;
321 }
323 /**
324 * Return this type as an <code>AnnotationTypeDoc</code> if it
325 * represents an annotation type. Array dimensions are ignored.
326 */
327 public AnnotationTypeDoc asAnnotationTypeDoc() {
328 return skipArrays().asAnnotationTypeDoc();
329 }
331 /**
332 * Return true if this is an array of a primitive type.
333 */
334 public boolean isPrimitive() {
335 return skipArrays().isPrimitive();
336 }
338 /**
339 * Return a string representation of the type.
340 *
341 * Return name of type including any dimension information.
342 * <p>
343 * For example, a two dimensional array of String returns
344 * <code>String[][]</code>.
345 *
346 * @return name of type including any dimension information.
347 */
348 @Override
349 public String toString() {
350 return qualifiedTypeName() + dimension();
351 }
352 }
353 }