--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java Wed Jan 23 20:57:40 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java Wed Jan 23 13:27:24 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,11 @@
package com.sun.tools.doclets.internal.toolkit.util;
import java.io.*;
+import java.lang.annotation.ElementType;
import java.util.*;
import com.sun.javadoc.*;
+import com.sun.javadoc.AnnotationDesc.ElementValuePair;
import com.sun.tools.doclets.internal.toolkit.*;
import javax.tools.StandardLocation;
@@ -304,9 +306,7 @@
//Try walking the tree.
addAllInterfaceTypes(results,
superType,
- superType instanceof ClassDoc ?
- ((ClassDoc) superType).interfaceTypes() :
- ((ParameterizedType) superType).interfaceTypes(),
+ interfaceTypesOf(superType),
false, configuration);
List<Type> resultsList = new ArrayList<Type>(results.values());
if (sort) {
@@ -315,6 +315,14 @@
return resultsList;
}
+ private static Type[] interfaceTypesOf(Type type) {
+ if (type instanceof AnnotatedType)
+ type = ((AnnotatedType)type).underlyingType();
+ return type instanceof ClassDoc ?
+ ((ClassDoc)type).interfaceTypes() :
+ ((ParameterizedType)type).interfaceTypes();
+ }
+
public static List<Type> getAllInterfaces(Type type, Configuration configuration) {
return getAllInterfaces(type, configuration, true);
}
@@ -325,9 +333,7 @@
if (superType == null)
return;
addAllInterfaceTypes(results, superType,
- superType instanceof ClassDoc ?
- ((ClassDoc) superType).interfaceTypes() :
- ((ParameterizedType) superType).interfaceTypes(),
+ interfaceTypesOf(superType),
raw, configuration);
}
@@ -337,9 +343,7 @@
if (superType == null)
return;
addAllInterfaceTypes(results, superType,
- superType instanceof ClassDoc ?
- ((ClassDoc) superType).interfaceTypes() :
- ((ParameterizedType) superType).interfaceTypes(),
+ interfaceTypesOf(superType),
false, configuration);
}
@@ -363,6 +367,9 @@
results.put(superInterface.asClassDoc(), superInterface);
}
}
+ if (type instanceof AnnotatedType)
+ type = ((AnnotatedType)type).underlyingType();
+
if (type instanceof ParameterizedType)
findAllInterfaceTypes(results, (ParameterizedType) type, configuration);
else if (((ClassDoc) type).typeParameters().length == 0)
@@ -494,6 +501,57 @@
return false;
}
+ private static boolean isDeclarationTarget(AnnotationDesc targetAnno) {
+ // The error recovery steps here are analogous to TypeAnnotations
+ ElementValuePair[] elems = targetAnno.elementValues();
+ if (elems == null
+ || elems.length != 1
+ || !"value".equals(elems[0].element().name())
+ || !(elems[0].value().value() instanceof AnnotationValue[]))
+ return true; // error recovery
+
+ AnnotationValue[] values = (AnnotationValue[])elems[0].value().value();
+ for (int i = 0; i < values.length; i++) {
+ Object value = values[i].value();
+ if (!(value instanceof FieldDoc))
+ return true; // error recovery
+
+ FieldDoc eValue = (FieldDoc)value;
+ if (Util.isJava5DeclarationElementType(eValue)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns true if the {@code annotationDoc} is to be treated
+ * as a declaration annotation, when targeting the
+ * {@code elemType} element type.
+ *
+ * @param annotationDoc the annotationDoc to check
+ * @param elemType the targeted elemType
+ * @return true if annotationDoc is a declaration annotation
+ */
+ public static boolean isDeclarationAnnotation(AnnotationTypeDoc annotationDoc,
+ boolean isJava5DeclarationLocation) {
+ if (!isJava5DeclarationLocation)
+ return false;
+ AnnotationDesc[] annotationDescList = annotationDoc.annotations();
+ // Annotations with no target are treated as declaration as well
+ if (annotationDescList.length==0)
+ return true;
+ for (int i = 0; i < annotationDescList.length; i++) {
+ if (annotationDescList[i].annotationType().qualifiedName().equals(
+ java.lang.annotation.Target.class.getName())) {
+ if (isDeclarationTarget(annotationDescList[i]))
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Return true if this class is linkable and false if we can't link to the
* desired class.
@@ -662,4 +720,25 @@
}
return false;
}
+
+ /**
+ * Test whether the given FieldDoc is one of the declaration annotation ElementTypes
+ * defined in Java 5.
+ * Instead of testing for one of the new enum constants added in Java 8, test for
+ * the old constants. This prevents bootstrapping problems.
+ *
+ * @param elt The FieldDoc to test
+ * @return true, iff the given ElementType is one of the constants defined in Java 5
+ * @since 1.8
+ */
+ public static boolean isJava5DeclarationElementType(FieldDoc elt) {
+ return elt.name().contentEquals(ElementType.ANNOTATION_TYPE.name()) ||
+ elt.name().contentEquals(ElementType.CONSTRUCTOR.name()) ||
+ elt.name().contentEquals(ElementType.FIELD.name()) ||
+ elt.name().contentEquals(ElementType.LOCAL_VARIABLE.name()) ||
+ elt.name().contentEquals(ElementType.METHOD.name()) ||
+ elt.name().contentEquals(ElementType.PACKAGE.name()) ||
+ elt.name().contentEquals(ElementType.PARAMETER.name()) ||
+ elt.name().contentEquals(ElementType.TYPE.name());
+ }
}