src/share/classes/com/sun/tools/javadoc/TypeMaker.java

Thu, 18 Apr 2013 20:00:14 -0700

author
jjg
date
Thu, 18 Apr 2013 20:00:14 -0700
changeset 1706
95d29b99e5b3
parent 1691
f10cffab99b4
child 1755
ddb4a2bfcd82
permissions
-rw-r--r--

8012656: cache frequently used name strings for DocImpl classes
Reviewed-by: darcy

     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 javax.lang.model.type.TypeKind;
    30 import com.sun.javadoc.*;
    31 import com.sun.tools.javac.code.Symbol;
    32 import com.sun.tools.javac.code.Symbol.ClassSymbol;
    33 import com.sun.tools.javac.code.Type;
    34 import com.sun.tools.javac.code.Type.ArrayType;
    35 import com.sun.tools.javac.code.Type.ClassType;
    36 import com.sun.tools.javac.code.Type.TypeVar;
    37 import com.sun.tools.javac.util.List;
    38 import static com.sun.tools.javac.code.TypeTag.ARRAY;
    40 /**
    41  *  <p><b>This is NOT part of any supported API.
    42  *  If you write code that depends on this, you do so at your own risk.
    43  *  This code and its internal interfaces are subject to change or
    44  *  deletion without notice.</b>
    45  */
    46 public class TypeMaker {
    48     public static com.sun.javadoc.Type getType(DocEnv env, Type t) {
    49         return getType(env, t, true);
    50     }
    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     }
    61     @SuppressWarnings("fallthrough")
    62     public static com.sun.javadoc.Type getType(DocEnv env, Type t,
    63             boolean errToClassDoc, boolean considerAnnotations) {
    64         if (env.legacyDoclet) {
    65             t = env.types.erasure(t);
    66         }
    67         if (considerAnnotations
    68                 && t.isAnnotated()) {
    69             return new AnnotatedTypeImpl(env, (com.sun.tools.javac.code.Type.AnnotatedType) t);
    70         }
    72         if (t.isAnnotated()) {
    73             Type.AnnotatedType at = (Type.AnnotatedType) t;
    74             return new AnnotatedTypeImpl(env, at);
    75         }
    77         switch (t.getTag()) {
    78         case CLASS:
    79             if (ClassDocImpl.isGeneric((ClassSymbol)t.tsym)) {
    80                 return env.getParameterizedType((ClassType)t);
    81             } else {
    82                 return env.getClassDoc((ClassSymbol)t.tsym);
    83             }
    84         case WILDCARD:
    85             Type.WildcardType a = (Type.WildcardType)t;
    86             return new WildcardTypeImpl(env, a);
    87         case TYPEVAR: return new TypeVariableImpl(env, (TypeVar)t);
    88         case ARRAY: return new ArrayTypeImpl(env, t);
    89         case BYTE: return PrimitiveType.byteType;
    90         case CHAR: return PrimitiveType.charType;
    91         case SHORT: return PrimitiveType.shortType;
    92         case INT: return PrimitiveType.intType;
    93         case LONG: return PrimitiveType.longType;
    94         case FLOAT: return PrimitiveType.floatType;
    95         case DOUBLE: return PrimitiveType.doubleType;
    96         case BOOLEAN: return PrimitiveType.booleanType;
    97         case VOID: return PrimitiveType.voidType;
    98         case ERROR:
    99             if (errToClassDoc)
   100                 return env.getClassDoc((ClassSymbol)t.tsym);
   101             // FALLTHRU
   102         default:
   103             return new PrimitiveType(t.tsym.getQualifiedName().toString());
   104         }
   105     }
   107     /**
   108      * Convert a list of javac types into an array of javadoc types.
   109      */
   110     public static com.sun.javadoc.Type[] getTypes(DocEnv env, List<Type> ts) {
   111         return getTypes(env, ts, new com.sun.javadoc.Type[ts.length()]);
   112     }
   114     /**
   115      * Like the above version, but use and return the array given.
   116      */
   117     public static com.sun.javadoc.Type[] getTypes(DocEnv env, List<Type> ts,
   118                                                   com.sun.javadoc.Type res[]) {
   119         int i = 0;
   120         for (Type t : ts) {
   121             res[i++] = getType(env, t);
   122         }
   123         return res;
   124     }
   126     public static String getTypeName(Type t, boolean full) {
   127         switch (t.getTag()) {
   128         case ARRAY:
   129             StringBuilder s = new StringBuilder();
   130             while (t.hasTag(ARRAY)) {
   131                 s.append("[]");
   132                 t = ((ArrayType)t).elemtype;
   133             }
   134             s.insert(0, getTypeName(t, full));
   135             return s.toString();
   136         case CLASS:
   137             return ClassDocImpl.getClassName((ClassSymbol)t.tsym, full);
   138         default:
   139             return t.tsym.getQualifiedName().toString();
   140         }
   141     }
   143     /**
   144      * Return the string representation of a type use.  Bounds of type
   145      * variables are not included; bounds of wildcard types are.
   146      * Class names are qualified if "full" is true.
   147      */
   148     static String getTypeString(DocEnv env, Type t, boolean full) {
   149         // TODO: should annotations be included here?
   150         if (t.isAnnotated()) {
   151             Type.AnnotatedType at = (Type.AnnotatedType)t;
   152             t = at.underlyingType;
   153         }
   154         switch (t.getTag()) {
   155         case ARRAY:
   156             StringBuilder s = new StringBuilder();
   157             while (t.hasTag(ARRAY)) {
   158                 s.append("[]");
   159                 t = env.types.elemtype(t);
   160             }
   161             s.insert(0, getTypeString(env, t, full));
   162             return s.toString();
   163         case CLASS:
   164             return ParameterizedTypeImpl.
   165                         parameterizedTypeToString(env, (ClassType)t, full);
   166         case WILDCARD:
   167             Type.WildcardType a = (Type.WildcardType)t;
   168             return WildcardTypeImpl.wildcardTypeToString(env, a, full);
   169         default:
   170             return t.tsym.getQualifiedName().toString();
   171         }
   172     }
   174     /**
   175      * Return the formal type parameters of a class or method as an
   176      * angle-bracketed string.  Each parameter is a type variable with
   177      * optional bounds.  Class names are qualified if "full" is true.
   178      * Return "" if there are no type parameters or we're hiding generics.
   179      */
   180     static String typeParametersString(DocEnv env, Symbol sym, boolean full) {
   181         if (env.legacyDoclet || sym.type.getTypeArguments().isEmpty()) {
   182             return "";
   183         }
   184         StringBuilder s = new StringBuilder();
   185         for (Type t : sym.type.getTypeArguments()) {
   186             s.append(s.length() == 0 ? "<" : ", ");
   187             s.append(TypeVariableImpl.typeVarToString(env, (TypeVar)t, full));
   188         }
   189         s.append(">");
   190         return s.toString();
   191     }
   193     /**
   194      * Return the actual type arguments of a parameterized type as an
   195      * angle-bracketed string.  Class name are qualified if "full" is true.
   196      * Return "" if there are no type arguments or we're hiding generics.
   197      */
   198     static String typeArgumentsString(DocEnv env, ClassType cl, boolean full) {
   199         if (env.legacyDoclet || cl.getTypeArguments().isEmpty()) {
   200             return "";
   201         }
   202         StringBuilder s = new StringBuilder();
   203         for (Type t : cl.getTypeArguments()) {
   204             s.append(s.length() == 0 ? "<" : ", ");
   205             s.append(getTypeString(env, t, full));
   206         }
   207         s.append(">");
   208         return s.toString();
   209     }
   212     private static class ArrayTypeImpl implements com.sun.javadoc.Type {
   214         Type arrayType;
   216         DocEnv env;
   218         ArrayTypeImpl(DocEnv env, Type arrayType) {
   219             this.env = env;
   220             this.arrayType = arrayType;
   221         }
   223         private com.sun.javadoc.Type skipArraysCache = null;
   225         public com.sun.javadoc.Type getElementType() {
   226             return TypeMaker.getType(env, env.types.elemtype(arrayType));
   227         }
   229         private com.sun.javadoc.Type skipArrays() {
   230             if (skipArraysCache == null) {
   231                 Type t;
   232                 for (t = arrayType; t.hasTag(ARRAY); t = env.types.elemtype(t)) { }
   233                 skipArraysCache = TypeMaker.getType(env, t);
   234             }
   235             return skipArraysCache;
   236         }
   238         /**
   239          * Return the type's dimension information, as a string.
   240          * <p>
   241          * For example, a two dimensional array of String returns '[][]'.
   242          */
   243         public String dimension() {
   244             StringBuilder dimension = new StringBuilder();
   245             for (Type t = arrayType; t.hasTag(ARRAY); t = env.types.elemtype(t)) {
   246                 dimension.append("[]");
   247             }
   248             return dimension.toString();
   249         }
   251         /**
   252          * Return unqualified name of type excluding any dimension information.
   253          * <p>
   254          * For example, a two dimensional array of String returns 'String'.
   255          */
   256         public String typeName() {
   257             return skipArrays().typeName();
   258         }
   260         /**
   261          * Return qualified name of type excluding any dimension information.
   262          *<p>
   263          * For example, a two dimensional array of String
   264          * returns 'java.lang.String'.
   265          */
   266         public String qualifiedTypeName() {
   267             return skipArrays().qualifiedTypeName();
   268         }
   270         /**
   271          * Return the simple name of this type excluding any dimension information.
   272          */
   273         public String simpleTypeName() {
   274             return skipArrays().simpleTypeName();
   275         }
   277         /**
   278          * Return this type as a class.  Array dimensions are ignored.
   279          *
   280          * @return a ClassDocImpl if the type is a Class.
   281          * Return null if it is a primitive type..
   282          */
   283         public ClassDoc asClassDoc() {
   284             return skipArrays().asClassDoc();
   285         }
   287         /**
   288          * Return this type as a <code>ParameterizedType</code> if it
   289          * represents a parameterized type.  Array dimensions are ignored.
   290          */
   291         public ParameterizedType asParameterizedType() {
   292             return skipArrays().asParameterizedType();
   293         }
   295         /**
   296          * Return this type as a <code>TypeVariable</code> if it represents
   297          * a type variable.  Array dimensions are ignored.
   298          */
   299         public TypeVariable asTypeVariable() {
   300             return skipArrays().asTypeVariable();
   301         }
   303         /**
   304          * Return null, as there are no arrays of wildcard types.
   305          */
   306         public WildcardType asWildcardType() {
   307             return null;
   308         }
   310         /**
   311          * Return null, as there are no annotations of the type
   312          */
   313         public AnnotatedType asAnnotatedType() {
   314             return null;
   315         }
   317         /**
   318          * Return this type as an <code>AnnotationTypeDoc</code> if it
   319          * represents an annotation type.  Array dimensions are ignored.
   320          */
   321         public AnnotationTypeDoc asAnnotationTypeDoc() {
   322             return skipArrays().asAnnotationTypeDoc();
   323         }
   325         /**
   326          * Return true if this is an array of a primitive type.
   327          */
   328         public boolean isPrimitive() {
   329             return skipArrays().isPrimitive();
   330         }
   332         /**
   333          * Return a string representation of the type.
   334          *
   335          * Return name of type including any dimension information.
   336          * <p>
   337          * For example, a two dimensional array of String returns
   338          * <code>String[][]</code>.
   339          *
   340          * @return name of type including any dimension information.
   341          */
   342         @Override
   343         public String toString() {
   344             return qualifiedTypeName() + dimension();
   345         }
   346     }
   347 }

mercurial