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 } |