src/share/classes/com/sun/tools/doclets/internal/toolkit/util/ClassUseMapper.java

Tue, 09 Oct 2012 19:10:00 -0700

author
jjg
date
Tue, 09 Oct 2012 19:10:00 -0700
changeset 1357
c75be5bc5283
parent 554
9d9f26857129
child 1359
25e14ad23cef
permissions
-rw-r--r--

8000663: clean up langtools imports
Reviewed-by: darcy

     1 /*
     2  * Copyright (c) 1998, 2012, 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.doclets.internal.toolkit.util;
    28 import java.util.*;
    30 import com.sun.javadoc.*;
    32 /**
    33  * Map all class uses for a given class.
    34  *
    35  * This code is not part of an API.
    36  * It is implementation that is subject to change.
    37  * Do not use it as an API
    38  *
    39  * @since 1.2
    40  * @author Robert G. Field
    41  */
    42 public class ClassUseMapper {
    44     private final ClassTree classtree;
    46     /**
    47      * Mapping of ClassDocs to set of PackageDoc used by that class.
    48      * Entries may be null.
    49      */
    50     public Map<String,Set<PackageDoc>> classToPackage = new HashMap<String,Set<PackageDoc>>();
    52     /**
    53      * Mapping of Annotations to set of PackageDoc that use the annotation.
    54      */
    55     public Map<String,List<PackageDoc>> classToPackageAnnotations = new HashMap<String,List<PackageDoc>>();
    57     /**
    58      * Mapping of ClassDocs to set of ClassDoc used by that class.
    59      * Entries may be null.
    60      */
    61     public Map<String,Set<ClassDoc>> classToClass = new HashMap<String,Set<ClassDoc>>();
    63     /**
    64      * Mapping of ClassDocs to list of ClassDoc which are direct or
    65      * indirect subclasses of that class.
    66      * Entries may be null.
    67      */
    68     public Map<String,List<ClassDoc>> classToSubclass = new HashMap<String,List<ClassDoc>>();
    70     /**
    71      * Mapping of ClassDocs to list of ClassDoc which are direct or
    72      * indirect subinterfaces of that interface.
    73      * Entries may be null.
    74      */
    75     public Map<String,List<ClassDoc>> classToSubinterface = new HashMap<String,List<ClassDoc>>();
    77     /**
    78      * Mapping of ClassDocs to list of ClassDoc which implement
    79      * this interface.
    80      * Entries may be null.
    81      */
    82     public Map<String,List<ClassDoc>> classToImplementingClass = new HashMap<String,List<ClassDoc>>();
    84     /**
    85      * Mapping of ClassDocs to list of FieldDoc declared as that class.
    86      * Entries may be null.
    87      */
    88     public Map<String,List<FieldDoc>> classToField = new HashMap<String,List<FieldDoc>>();
    90     /**
    91      * Mapping of ClassDocs to list of MethodDoc returning that class.
    92      * Entries may be null.
    93      */
    94     public Map<String,List<MethodDoc>> classToMethodReturn = new HashMap<String,List<MethodDoc>>();
    96     /**
    97      * Mapping of ClassDocs to list of MethodDoc having that class
    98      * as an arg.
    99      * Entries may be null.
   100      */
   101     public Map<String,List<ExecutableMemberDoc>> classToMethodArgs = new HashMap<String,List<ExecutableMemberDoc>>();
   103     /**
   104      * Mapping of ClassDocs to list of MethodDoc which throws that class.
   105      * Entries may be null.
   106      */
   107     public Map<String,List<ExecutableMemberDoc>> classToMethodThrows = new HashMap<String,List<ExecutableMemberDoc>>();
   109     /**
   110      * Mapping of ClassDocs to list of ConstructorDoc having that class
   111      * as an arg.
   112      * Entries may be null.
   113      */
   114     public Map<String,List<ExecutableMemberDoc>> classToConstructorArgs = new HashMap<String,List<ExecutableMemberDoc>>();
   116     /**
   117      * Mapping of ClassDocs to list of ConstructorDoc which throws that class.
   118      * Entries may be null.
   119      */
   120     public Map<String,List<ExecutableMemberDoc>> classToConstructorThrows = new HashMap<String,List<ExecutableMemberDoc>>();
   122     /**
   123      * The mapping of AnnotationTypeDocs to constructors that use them.
   124      */
   125     public Map<String,List<ConstructorDoc>> classToConstructorAnnotations = new HashMap<String,List<ConstructorDoc>>();
   127     /**
   128      * The mapping of AnnotationTypeDocs to Constructor parameters that use them.
   129      */
   130     public Map<String,List<ExecutableMemberDoc>> classToConstructorParamAnnotation = new HashMap<String,List<ExecutableMemberDoc>>();
   132     /**
   133      * The mapping of ClassDocs to Constructor arguments that use them as type parameters.
   134      */
   135     public Map<String,List<ExecutableMemberDoc>> classToConstructorDocArgTypeParam = new HashMap<String,List<ExecutableMemberDoc>>();
   137     /**
   138      * The mapping of ClassDocs to ClassDocs that use them as type parameters.
   139      */
   140     public Map<String,List<ClassDoc>> classToClassTypeParam = new HashMap<String,List<ClassDoc>>();
   142     /**
   143      * The mapping of AnnotationTypeDocs to ClassDocs that use them.
   144      */
   145     public Map<String,List<ClassDoc>> classToClassAnnotations = new HashMap<String,List<ClassDoc>>();
   147     /**
   148      * The mapping of ClassDocs to ExecutableMemberDocs that use them as type parameters.
   149      */
   150     public Map<String,List<MethodDoc>> classToExecMemberDocTypeParam = new HashMap<String,List<MethodDoc>>();
   152     /**
   153      * The mapping of ClassDocs to ExecutableMemberDocs arguments that use them as type parameters.
   154      */
   155     public Map<String,List<ExecutableMemberDoc>> classToExecMemberDocArgTypeParam = new HashMap<String,List<ExecutableMemberDoc>>();
   157     /**
   158      * The mapping of AnnotationTypeDocs to ExecutableMemberDocs that use them.
   159      */
   160     public Map<String,List<MethodDoc>> classToExecMemberDocAnnotations = new HashMap<String,List<MethodDoc>>();
   162     /**
   163      * The mapping of ClassDocs to ExecutableMemberDocs that have return type
   164      * with type parameters of that class.
   165      */
   166     public Map<String,List<MethodDoc>> classToExecMemberDocReturnTypeParam = new HashMap<String,List<MethodDoc>>();
   168     /**
   169      * The mapping of AnnotationTypeDocs to MethodDoc parameters that use them.
   170      */
   171     public Map<String,List<ExecutableMemberDoc>> classToExecMemberDocParamAnnotation = new HashMap<String,List<ExecutableMemberDoc>>();
   173     /**
   174      * The mapping of ClassDocs to FieldDocs that use them as type parameters.
   175      */
   176     public Map<String,List<FieldDoc>> classToFieldDocTypeParam = new HashMap<String,List<FieldDoc>>();
   178     /**
   179      * The mapping of AnnotationTypeDocs to FieldDocs that use them.
   180      */
   181     public Map<String,List<FieldDoc>> annotationToFieldDoc = new HashMap<String,List<FieldDoc>>();
   184     public ClassUseMapper(RootDoc root, ClassTree classtree) {
   185         this.classtree = classtree;
   187         // Map subclassing, subinterfacing implementing, ...
   188         for (Iterator<ClassDoc> it = classtree.baseclasses().iterator(); it.hasNext();) {
   189             subclasses(it.next());
   190         }
   191         for (Iterator<ClassDoc> it = classtree.baseinterfaces().iterator(); it.hasNext();) {
   192             // does subinterfacing as side-effect
   193             implementingClasses(it.next());
   194         }
   195         // Map methods, fields, constructors using a class.
   196         ClassDoc[] classes = root.classes();
   197         for (int i = 0; i < classes.length; i++) {
   198             PackageDoc pkg = classes[i].containingPackage();
   199             mapAnnotations(classToPackageAnnotations, pkg, pkg);
   200             ClassDoc cd = classes[i];
   201             mapTypeParameters(classToClassTypeParam, cd, cd);
   202             mapAnnotations(classToClassAnnotations, cd, cd);
   203             FieldDoc[] fields = cd.fields();
   204             for (int j = 0; j < fields.length; j++) {
   205                 FieldDoc fd = fields[j];
   206                 mapTypeParameters(classToFieldDocTypeParam, fd, fd);
   207                 mapAnnotations(annotationToFieldDoc, fd, fd);
   208                 if (! fd.type().isPrimitive()) {
   209                     add(classToField, fd.type().asClassDoc(), fd);
   210                 }
   211             }
   212             ConstructorDoc[] cons = cd.constructors();
   213             for (int j = 0; j < cons.length; j++) {
   214                 mapAnnotations(classToConstructorAnnotations, cons[j], cons[j]);
   215                 mapExecutable(cons[j]);
   216             }
   217             MethodDoc[] meths = cd.methods();
   218             for (int j = 0; j < meths.length; j++) {
   219                 MethodDoc md = meths[j];
   220                 mapExecutable(md);
   221                 mapTypeParameters(classToExecMemberDocTypeParam, md, md);
   222                 mapAnnotations(classToExecMemberDocAnnotations, md, md);
   223                 if (! (md.returnType().isPrimitive() || md.returnType() instanceof TypeVariable)) {
   224                     mapTypeParameters(classToExecMemberDocReturnTypeParam,
   225                         md.returnType(), md);
   226                     add(classToMethodReturn, md.returnType().asClassDoc(), md);
   227                 }
   228             }
   229         }
   230     }
   232     /**
   233      * Return all subclasses of a class AND fill-in classToSubclass map.
   234      */
   235     private Collection<ClassDoc> subclasses(ClassDoc cd) {
   236         Collection<ClassDoc> ret = classToSubclass.get(cd.qualifiedName());
   237         if (ret == null) {
   238             ret = new TreeSet<ClassDoc>();
   239             List<ClassDoc> subs = classtree.subclasses(cd);
   240             if (subs != null) {
   241                 ret.addAll(subs);
   242                 for (Iterator<ClassDoc> it = subs.iterator(); it.hasNext();) {
   243                     ret.addAll(subclasses(it.next()));
   244                 }
   245             }
   246             addAll(classToSubclass, cd, ret);
   247         }
   248         return ret;
   249     }
   251     /**
   252      * Return all subinterfaces of an interface AND fill-in classToSubinterface map.
   253      */
   254     private Collection<ClassDoc> subinterfaces(ClassDoc cd) {
   255         Collection<ClassDoc> ret = classToSubinterface.get(cd.qualifiedName());
   256         if (ret == null) {
   257             ret = new TreeSet<ClassDoc>();
   258             List<ClassDoc> subs = classtree.subinterfaces(cd);
   259             if (subs != null) {
   260                 ret.addAll(subs);
   261                 for (Iterator<ClassDoc> it = subs.iterator(); it.hasNext();) {
   262                     ret.addAll(subinterfaces(it.next()));
   263                 }
   264             }
   265             addAll(classToSubinterface, cd, ret);
   266         }
   267         return ret;
   268     }
   270     /**
   271      * Return all implementing classes of an interface (including
   272      * all subclasses of implementing classes and all classes
   273      * implementing subinterfaces) AND fill-in both classToImplementingClass
   274      * and classToSubinterface maps.
   275      */
   276     private Collection<ClassDoc> implementingClasses(ClassDoc cd) {
   277         Collection<ClassDoc> ret = classToImplementingClass.get(cd.qualifiedName());
   278         if (ret == null) {
   279             ret = new TreeSet<ClassDoc>();
   280             List<ClassDoc> impl = classtree.implementingclasses(cd);
   281             if (impl != null) {
   282                 ret.addAll(impl);
   283                 for (Iterator<ClassDoc> it = impl.iterator(); it.hasNext();) {
   284                     ret.addAll(subclasses(it.next()));
   285                 }
   286             }
   287             for (Iterator<ClassDoc> it = subinterfaces(cd).iterator(); it.hasNext();) {
   288                 ret.addAll(implementingClasses(it.next()));
   289             }
   290             addAll(classToImplementingClass, cd, ret);
   291         }
   292         return ret;
   293     }
   295     /**
   296      * Determine classes used by a method or constructor, so they can be
   297      * inverse mapped.
   298      */
   299     private void mapExecutable(ExecutableMemberDoc em) {
   300         Parameter[] params = em.parameters();
   301         boolean isConstructor = em.isConstructor();
   302         List<Type> classArgs = new ArrayList<Type>();
   303         for (int k = 0; k < params.length; k++) {
   304             Type pcd = params[k].type();
   305             // primitives don't get mapped, also avoid dups
   306             if ((! params[k].type().isPrimitive()) &&
   307                  ! classArgs.contains(pcd) &&
   308                  ! (pcd instanceof TypeVariable)) {
   309                 add(isConstructor? classToConstructorArgs :classToMethodArgs,
   310                         pcd.asClassDoc(), em);
   311                 classArgs.add(pcd);
   312                 mapTypeParameters(isConstructor?
   313                    classToConstructorDocArgTypeParam : classToExecMemberDocArgTypeParam,
   314                    pcd, em);
   315             }
   316             mapAnnotations(
   317                 isConstructor ?
   318                     classToConstructorParamAnnotation :
   319                     classToExecMemberDocParamAnnotation,
   320                 params[k], em);
   321         }
   322         ClassDoc[] thr = em.thrownExceptions();
   323         for (int k = 0; k < thr.length; k++) {
   324             add(isConstructor? classToConstructorThrows : classToMethodThrows,
   325                     thr[k], em);
   326         }
   327     }
   329     private <T> List<T> refList(Map<String,List<T>> map, ClassDoc cd) {
   330         List<T> list = map.get(cd.qualifiedName());
   331         if (list == null) {
   332             List<T> l = new ArrayList<T>();
   333             list = l;
   334             map.put(cd.qualifiedName(), list);
   335         }
   336         return list;
   337     }
   339     private Set<PackageDoc> packageSet(ClassDoc cd) {
   340         Set<PackageDoc> pkgSet = classToPackage.get(cd.qualifiedName());
   341         if (pkgSet == null) {
   342             pkgSet = new TreeSet<PackageDoc>();
   343             classToPackage.put(cd.qualifiedName(), pkgSet);
   344         }
   345         return pkgSet;
   346     }
   348     private Set<ClassDoc> classSet(ClassDoc cd) {
   349         Set<ClassDoc> clsSet = classToClass.get(cd.qualifiedName());
   350         if (clsSet == null) {
   351             Set<ClassDoc> s = new TreeSet<ClassDoc>();
   352             clsSet = s;
   353             classToClass.put(cd.qualifiedName(), clsSet);
   354         }
   355         return clsSet;
   356     }
   358     private <T extends ProgramElementDoc> void add(Map<String,List<T>> map, ClassDoc cd, T ref) {
   359         // add to specified map
   360         refList(map, cd).add(ref);
   362         // add ref's package to package map and class map
   363         packageSet(cd).add(ref.containingPackage());
   365         classSet(cd).add(ref instanceof MemberDoc?
   366                 ((MemberDoc)ref).containingClass() :
   367                     (ClassDoc)ref);
   368     }
   370     private void addAll(Map<String,List<ClassDoc>> map, ClassDoc cd, Collection<ClassDoc> refs) {
   371         if (refs == null) {
   372             return;
   373         }
   374         // add to specified map
   375         refList(map, cd).addAll(refs);
   377         Set<PackageDoc> pkgSet = packageSet(cd);
   378         Set<ClassDoc> clsSet = classSet(cd);
   379         // add ref's package to package map and class map
   380         for (Iterator<ClassDoc> it = refs.iterator(); it.hasNext();) {
   381             ClassDoc cls = it.next();
   382             pkgSet.add(cls.containingPackage());
   383             clsSet.add(cls);
   385         }
   386     }
   388     /**
   389      * Map the ClassDocs to the ProgramElementDocs that use them as
   390      * type parameters.
   391      *
   392      * @param map the map the insert the information into.
   393      * @param doc the doc whose type parameters are being checked.
   394      * @param holder the holder that owns the type parameters.
   395      */
   396     private <T extends ProgramElementDoc> void mapTypeParameters(Map<String,List<T>> map, Object doc,
   397             T holder) {
   398         TypeVariable[] typeVariables;
   399         if (doc instanceof ClassDoc) {
   400             typeVariables = ((ClassDoc) doc).typeParameters();
   401         } else if (doc instanceof WildcardType) {
   402             Type[] extendsBounds = ((WildcardType) doc).extendsBounds();
   403             for (int k = 0; k < extendsBounds.length; k++) {
   404                 addTypeParameterToMap(map, extendsBounds[k], holder);
   405             }
   406             Type[] superBounds = ((WildcardType) doc).superBounds();
   407             for (int k = 0; k < superBounds.length; k++) {
   408                 addTypeParameterToMap(map, superBounds[k], holder);
   409             }
   410             return;
   411         } else if (doc instanceof ParameterizedType) {
   412             Type[] typeArguments = ((ParameterizedType) doc).typeArguments();
   413             for (int k = 0; k < typeArguments.length; k++) {
   414                 addTypeParameterToMap(map, typeArguments[k], holder);
   415             }
   416             return;
   417         } else if (doc instanceof ExecutableMemberDoc) {
   418             typeVariables = ((ExecutableMemberDoc) doc).typeParameters();
   419         } else if (doc instanceof FieldDoc) {
   420             Type fieldType = ((FieldDoc) doc).type();
   421             mapTypeParameters(map, fieldType, holder);
   422             return;
   423         } else {
   424             return;
   425         }
   426         for (int i = 0; i < typeVariables.length; i++) {
   427             Type[] bounds = typeVariables[i].bounds();
   428             for (int j = 0; j < bounds.length; j++) {
   429                 addTypeParameterToMap(map, bounds[j], holder);
   430             }
   431         }
   432     }
   434     /**
   435      * Map the AnnotationType to the ProgramElementDocs that use them as
   436      * type parameters.
   437      *
   438      * @param map the map the insert the information into.
   439      * @param doc the doc whose type parameters are being checked.
   440      * @param holder the holder that owns the type parameters.
   441      */
   442     private <T extends ProgramElementDoc> void mapAnnotations(Map<String,List<T>> map, Object doc,
   443             T holder) {
   444         AnnotationDesc[] annotations;
   445         boolean isPackage = false;
   446         if (doc instanceof ProgramElementDoc) {
   447             annotations = ((ProgramElementDoc) doc).annotations();
   448         } else if (doc instanceof PackageDoc) {
   449             annotations = ((PackageDoc) doc).annotations();
   450             isPackage = true;
   451         } else if (doc instanceof Parameter) {
   452             annotations = ((Parameter) doc).annotations();
   453         } else {
   454             throw new DocletAbortException();
   455         }
   456         for (int i = 0; i < annotations.length; i++) {
   457             AnnotationTypeDoc annotationDoc = annotations[i].annotationType();
   458             if (isPackage)
   459                 refList(map, annotationDoc).add(holder);
   460             else
   461                 add(map, annotationDoc, holder);
   462         }
   463     }
   466     /**
   467      * Map the AnnotationType to the ProgramElementDocs that use them as
   468      * type parameters.
   469      *
   470      * @param map the map the insert the information into.
   471      * @param doc the doc whose type parameters are being checked.
   472      * @param holder the holder that owns the type parameters.
   473      */
   474     private <T extends PackageDoc> void mapAnnotations(Map<String,List<T>> map, PackageDoc doc,
   475             T holder) {
   476         AnnotationDesc[] annotations;
   477         annotations = doc.annotations();
   478         for (int i = 0; i < annotations.length; i++) {
   479             AnnotationTypeDoc annotationDoc = annotations[i].annotationType();
   480             refList(map, annotationDoc).add(holder);
   481         }
   482     }
   484     private <T extends ProgramElementDoc> void addTypeParameterToMap(Map<String,List<T>> map, Type type,
   485             T holder) {
   486         if (type instanceof ClassDoc) {
   487             add(map, (ClassDoc) type, holder);
   488         } else if (type instanceof ParameterizedType) {
   489             add(map, ((ParameterizedType) type).asClassDoc(), holder);
   490         }
   491         mapTypeParameters(map, type, holder);
   492     }
   493 }

mercurial