langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
changeset 15385 ee1eebe7e210
parent 14542 7062120649c2
child 16319 e586bfeb39c5
equal deleted inserted replaced
15384:5a8d00abf076 15385:ee1eebe7e210
     1 /*
     1 /*
     2  * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    24  */
    24  */
    25 
    25 
    26 package com.sun.tools.doclets.internal.toolkit.util;
    26 package com.sun.tools.doclets.internal.toolkit.util;
    27 
    27 
    28 import java.io.*;
    28 import java.io.*;
       
    29 import java.lang.annotation.ElementType;
    29 import java.util.*;
    30 import java.util.*;
    30 
    31 
    31 import com.sun.javadoc.*;
    32 import com.sun.javadoc.*;
       
    33 import com.sun.javadoc.AnnotationDesc.ElementValuePair;
    32 import com.sun.tools.doclets.internal.toolkit.*;
    34 import com.sun.tools.doclets.internal.toolkit.*;
    33 import javax.tools.StandardLocation;
    35 import javax.tools.StandardLocation;
    34 
    36 
    35 /**
    37 /**
    36  * Utilities Class for Doclets.
    38  * Utilities Class for Doclets.
   302         if (superType == null)
   304         if (superType == null)
   303             return new ArrayList<Type>(results.values());
   305             return new ArrayList<Type>(results.values());
   304         //Try walking the tree.
   306         //Try walking the tree.
   305         addAllInterfaceTypes(results,
   307         addAllInterfaceTypes(results,
   306             superType,
   308             superType,
   307             superType instanceof ClassDoc ?
   309             interfaceTypesOf(superType),
   308                 ((ClassDoc) superType).interfaceTypes() :
       
   309                 ((ParameterizedType) superType).interfaceTypes(),
       
   310             false, configuration);
   310             false, configuration);
   311         List<Type> resultsList = new ArrayList<Type>(results.values());
   311         List<Type> resultsList = new ArrayList<Type>(results.values());
   312         if (sort) {
   312         if (sort) {
   313                 Collections.sort(resultsList, new TypeComparator());
   313                 Collections.sort(resultsList, new TypeComparator());
   314         }
   314         }
   315         return resultsList;
   315         return resultsList;
       
   316     }
       
   317 
       
   318     private static Type[] interfaceTypesOf(Type type) {
       
   319         if (type instanceof AnnotatedType)
       
   320             type = ((AnnotatedType)type).underlyingType();
       
   321         return type instanceof ClassDoc ?
       
   322                 ((ClassDoc)type).interfaceTypes() :
       
   323                 ((ParameterizedType)type).interfaceTypes();
   316     }
   324     }
   317 
   325 
   318     public static List<Type> getAllInterfaces(Type type, Configuration configuration) {
   326     public static List<Type> getAllInterfaces(Type type, Configuration configuration) {
   319         return getAllInterfaces(type, configuration, true);
   327         return getAllInterfaces(type, configuration, true);
   320     }
   328     }
   323             Configuration configuration) {
   331             Configuration configuration) {
   324         Type superType = c.superclassType();
   332         Type superType = c.superclassType();
   325         if (superType == null)
   333         if (superType == null)
   326             return;
   334             return;
   327         addAllInterfaceTypes(results, superType,
   335         addAllInterfaceTypes(results, superType,
   328                 superType instanceof ClassDoc ?
   336                 interfaceTypesOf(superType),
   329                 ((ClassDoc) superType).interfaceTypes() :
       
   330                 ((ParameterizedType) superType).interfaceTypes(),
       
   331                 raw, configuration);
   337                 raw, configuration);
   332     }
   338     }
   333 
   339 
   334     private static void findAllInterfaceTypes(Map<ClassDoc,Type> results, ParameterizedType p,
   340     private static void findAllInterfaceTypes(Map<ClassDoc,Type> results, ParameterizedType p,
   335             Configuration configuration) {
   341             Configuration configuration) {
   336         Type superType = p.superclassType();
   342         Type superType = p.superclassType();
   337         if (superType == null)
   343         if (superType == null)
   338             return;
   344             return;
   339         addAllInterfaceTypes(results, superType,
   345         addAllInterfaceTypes(results, superType,
   340                 superType instanceof ClassDoc ?
   346                 interfaceTypesOf(superType),
   341                 ((ClassDoc) superType).interfaceTypes() :
       
   342                 ((ParameterizedType) superType).interfaceTypes(),
       
   343                 false, configuration);
   347                 false, configuration);
   344     }
   348     }
   345 
   349 
   346     private static void addAllInterfaceTypes(Map<ClassDoc,Type> results, Type type,
   350     private static void addAllInterfaceTypes(Map<ClassDoc,Type> results, Type type,
   347             Type[] interfaceTypes, boolean raw,
   351             Type[] interfaceTypes, boolean raw,
   361             for (Iterator<Type> iter = superInterfaces.iterator(); iter.hasNext(); ) {
   365             for (Iterator<Type> iter = superInterfaces.iterator(); iter.hasNext(); ) {
   362                 Type superInterface = iter.next();
   366                 Type superInterface = iter.next();
   363                 results.put(superInterface.asClassDoc(), superInterface);
   367                 results.put(superInterface.asClassDoc(), superInterface);
   364             }
   368             }
   365         }
   369         }
       
   370         if (type instanceof AnnotatedType)
       
   371             type = ((AnnotatedType)type).underlyingType();
       
   372 
   366         if (type instanceof ParameterizedType)
   373         if (type instanceof ParameterizedType)
   367             findAllInterfaceTypes(results, (ParameterizedType) type, configuration);
   374             findAllInterfaceTypes(results, (ParameterizedType) type, configuration);
   368         else if (((ClassDoc) type).typeParameters().length == 0)
   375         else if (((ClassDoc) type).typeParameters().length == 0)
   369             findAllInterfaceTypes(results, (ClassDoc) type, raw, configuration);
   376             findAllInterfaceTypes(results, (ClassDoc) type, raw, configuration);
   370         else
   377         else
   492             }
   499             }
   493         }
   500         }
   494         return false;
   501         return false;
   495     }
   502     }
   496 
   503 
       
   504     private static boolean isDeclarationTarget(AnnotationDesc targetAnno) {
       
   505         // The error recovery steps here are analogous to TypeAnnotations
       
   506         ElementValuePair[] elems = targetAnno.elementValues();
       
   507         if (elems == null
       
   508             || elems.length != 1
       
   509             || !"value".equals(elems[0].element().name())
       
   510             || !(elems[0].value().value() instanceof AnnotationValue[]))
       
   511             return true;    // error recovery
       
   512 
       
   513         AnnotationValue[] values = (AnnotationValue[])elems[0].value().value();
       
   514         for (int i = 0; i < values.length; i++) {
       
   515             Object value = values[i].value();
       
   516             if (!(value instanceof FieldDoc))
       
   517                 return true; // error recovery
       
   518 
       
   519             FieldDoc eValue = (FieldDoc)value;
       
   520             if (Util.isJava5DeclarationElementType(eValue)) {
       
   521                 return true;
       
   522             }
       
   523         }
       
   524 
       
   525         return false;
       
   526     }
       
   527 
       
   528     /**
       
   529      * Returns true if the {@code annotationDoc} is to be treated
       
   530      * as a declaration annotation, when targeting the
       
   531      * {@code elemType} element type.
       
   532      *
       
   533      * @param annotationDoc the annotationDoc to check
       
   534      * @param elemType  the targeted elemType
       
   535      * @return true if annotationDoc is a declaration annotation
       
   536      */
       
   537     public static boolean isDeclarationAnnotation(AnnotationTypeDoc annotationDoc,
       
   538             boolean isJava5DeclarationLocation) {
       
   539         if (!isJava5DeclarationLocation)
       
   540             return false;
       
   541         AnnotationDesc[] annotationDescList = annotationDoc.annotations();
       
   542         // Annotations with no target are treated as declaration as well
       
   543         if (annotationDescList.length==0)
       
   544             return true;
       
   545         for (int i = 0; i < annotationDescList.length; i++) {
       
   546             if (annotationDescList[i].annotationType().qualifiedName().equals(
       
   547                     java.lang.annotation.Target.class.getName())) {
       
   548                 if (isDeclarationTarget(annotationDescList[i]))
       
   549                     return true;
       
   550             }
       
   551         }
       
   552         return false;
       
   553     }
       
   554 
   497     /**
   555     /**
   498      * Return true if this class is linkable and false if we can't link to the
   556      * Return true if this class is linkable and false if we can't link to the
   499      * desired class.
   557      * desired class.
   500      * <br>
   558      * <br>
   501      * <b>NOTE:</b>  You can only link to external classes if they are public or
   559      * <b>NOTE:</b>  You can only link to external classes if they are public or
   660                 return true;
   718                 return true;
   661             }
   719             }
   662         }
   720         }
   663         return false;
   721         return false;
   664     }
   722     }
       
   723 
       
   724     /**
       
   725      * Test whether the given FieldDoc is one of the declaration annotation ElementTypes
       
   726      * defined in Java 5.
       
   727      * Instead of testing for one of the new enum constants added in Java 8, test for
       
   728      * the old constants. This prevents bootstrapping problems.
       
   729      *
       
   730      * @param elt The FieldDoc to test
       
   731      * @return true, iff the given ElementType is one of the constants defined in Java 5
       
   732      * @since 1.8
       
   733      */
       
   734     public static boolean isJava5DeclarationElementType(FieldDoc elt) {
       
   735         return elt.name().contentEquals(ElementType.ANNOTATION_TYPE.name()) ||
       
   736                 elt.name().contentEquals(ElementType.CONSTRUCTOR.name()) ||
       
   737                 elt.name().contentEquals(ElementType.FIELD.name()) ||
       
   738                 elt.name().contentEquals(ElementType.LOCAL_VARIABLE.name()) ||
       
   739                 elt.name().contentEquals(ElementType.METHOD.name()) ||
       
   740                 elt.name().contentEquals(ElementType.PACKAGE.name()) ||
       
   741                 elt.name().contentEquals(ElementType.PARAMETER.name()) ||
       
   742                 elt.name().contentEquals(ElementType.TYPE.name());
       
   743     }
   665 }
   744 }