8182108: javadoc makes up type variables for grandparent types

Reviewed-by: jjg
This commit is contained in:
Kumar Srinivasan 2017-11-29 15:27:47 -08:00
parent 97cddabb17
commit 581c28572a
4 changed files with 159 additions and 91 deletions

View File

@ -151,21 +151,6 @@ public class WorkArounds {
return (doclint == null); return (doclint == null);
} }
// TODO: jx.l.m directSuperTypes don't work for things like Enum,
// so we use javac directly, investigate why jx.l.m is not cutting it.
public List<TypeMirror> interfaceTypesOf(TypeMirror type) {
com.sun.tools.javac.util.List<com.sun.tools.javac.code.Type> interfaces =
((DocEnvImpl)configuration.docEnv).toolEnv.getTypes().interfaces((com.sun.tools.javac.code.Type)type);
if (interfaces.isEmpty()) {
return Collections.emptyList();
}
List<TypeMirror> list = new ArrayList<>(interfaces.size());
for (com.sun.tools.javac.code.Type t : interfaces) {
list.add((TypeMirror)t);
}
return list;
}
/* /*
* TODO: This method exists because of a bug in javac which does not * TODO: This method exists because of a bug in javac which does not
* handle "@deprecated tag in package-info.java", when this issue * handle "@deprecated tag in package-info.java", when this issue

View File

@ -55,6 +55,8 @@ import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.NoType; import javax.lang.model.type.NoType;
import javax.lang.model.type.PrimitiveType; import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.type.WildcardType;
import javax.lang.model.util.ElementFilter; import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.ElementKindVisitor9; import javax.lang.model.util.ElementKindVisitor9;
import javax.lang.model.util.Elements; import javax.lang.model.util.Elements;
@ -976,71 +978,40 @@ public class Utils {
} }
/** /**
* For the class return all implemented interfaces including the * Returns all the implemented super-interfaces of a given type,
* superinterfaces of the implementing interfaces, also iterate over for * in the case of classes, include all the super-interfaces of
* all the superclasses. For interface return all the extended interfaces * the supertype. The super-interfaces are collected before the
* as well as superinterfaces for those extended interfaces. * super-interfaces of the supertype.
* *
* @param te the class to get the interfaces for * @param te the type element to get the super-interfaces for.
* @return List of all the required interfaces. * @return the list of super-interfaces.
*/ */
public Set<TypeMirror> getAllInterfaces(TypeElement te) { public Set<TypeMirror> getAllInterfaces(TypeElement te) {
Set<TypeMirror> results = new LinkedHashSet<>(); Set<TypeMirror> results = new LinkedHashSet<>();
getAllInterfaces(te.asType(), results);
List<? extends TypeMirror> interfaceTypes = te.getInterfaces();
for (TypeMirror interfaceType : interfaceTypes) {
TypeElement intfc = asTypeElement(interfaceType);
if (isPublic(intfc) || isLinkable(intfc)) {
results.add(interfaceType);
TypeElement klass = asTypeElement(interfaceType);
for (TypeMirror t : getAllInterfaces(klass)) {
t = getDeclaredType(results, te, t);
results.add(t);
}
}
}
// TypeMirror contains the modified TypeParameterElement's types represented
// in the local Class'es elements types. ex: Foo<E> implements Bar<V> and the
// class being considered is Foo then TypeParameters will be represented as <E>
// note that any conversion might revert back to the old signature. For this
// very reason we get the superType, and find its interfaces.
TypeMirror superType = getSuperType(te);
if (superType == getObjectType())
return results;
// Try walking the tree
addAllInterfaceTypes(results, te, superType,
configuration.workArounds.interfaceTypesOf(superType));
return results; return results;
} }
private void findAllInterfaceTypes(Set<TypeMirror> results, final TypeElement baseClass, private void getAllInterfaces(TypeMirror type, Set<TypeMirror> results) {
TypeMirror p) { List<? extends TypeMirror> intfacs = typeUtils.directSupertypes(type);
TypeMirror superType = getSuperType(asTypeElement(p)); TypeMirror superType = null;
if (superType == p) { for (TypeMirror intfac : intfacs) {
return; if (intfac == getObjectType())
} continue;
addAllInterfaceTypes(results, baseClass, superType, TypeElement e = asTypeElement(intfac);
configuration.workArounds.interfaceTypesOf(superType)); if (isInterface(e)) {
} if (isPublic(e) || isLinkable(e))
results.add(intfac);
private void addAllInterfaceTypes(Set<TypeMirror> results, getAllInterfaces(intfac, results);
final TypeElement baseClass, TypeMirror type, } else {
List<TypeMirror> interfaceTypes) { // Save the supertype for later.
for (TypeMirror interfaceType : interfaceTypes) { superType = intfac;
TypeElement iElement = asTypeElement(interfaceType);
if (isPublic(iElement) && isLinkable(iElement)) {
interfaceType = getDeclaredType(results, baseClass, interfaceType);
results.add(interfaceType);
Set<TypeMirror> superInterfaces = getAllInterfaces(iElement);
for (TypeMirror superInterface : superInterfaces) {
superInterface = getDeclaredType(results, baseClass, superInterface);
results.add(superInterface);
}
} }
} }
findAllInterfaceTypes(results, baseClass, type); // Collect the super-interfaces of the supertype.
if (superType != null)
getAllInterfaces(superType, results);
} }
/** /**
@ -1154,22 +1125,6 @@ public class Utils {
(isPublic(typeElem) || isProtected(typeElem))); (isPublic(typeElem) || isProtected(typeElem)));
} }
List<TypeMirror> asErasureTypes(Collection<TypeElement> inList) {
List<TypeMirror> out = new ArrayList<>(inList.size());
inList.stream().forEach((te) -> {
out.add(typeUtils.erasure(te.asType()));
});
return out;
}
List<TypeMirror> asTypes(Collection<TypeElement> inList) {
List<TypeMirror> out = new ArrayList<>(inList.size());
inList.stream().forEach((te) -> {
out.add(te.asType());
});
return out;
}
/** /**
* Return this type as a {@code TypeElement} if it represents a class * Return this type as a {@code TypeElement} if it represents a class
* interface or annotation. Array dimensions are ignored. * interface or annotation. Array dimensions are ignored.
@ -1195,10 +1150,9 @@ public class Utils {
} }
@Override @Override
public TypeElement visitTypeVariable(javax.lang.model.type.TypeVariable t, Void p) { public TypeElement visitTypeVariable(TypeVariable t, Void p) {
/* /* TODO, this may not be an optimimal fix.
* TODO: Check with JJG. * if we have an annotated type @DA T, then erasure returns a
* if we have an annotated type @A $B T, then erasure returns a
* none, in this case we use asElement instead. * none, in this case we use asElement instead.
*/ */
if (isAnnotated(t)) { if (isAnnotated(t)) {
@ -1208,7 +1162,7 @@ public class Utils {
} }
@Override @Override
public TypeElement visitWildcard(javax.lang.model.type.WildcardType t, Void p) { public TypeElement visitWildcard(WildcardType t, Void p) {
return visit(typeUtils.erasure(t)); return visit(typeUtils.erasure(t));
} }

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8182108
* @summary Verify that grand parent interface types are correct, and
* various interface related sections are correctly generated.
* @library ../lib
* @modules jdk.javadoc/jdk.javadoc.internal.tool
* @build JavadocTester
* @run main TestGrandParentTypes
*/
public class TestGrandParentTypes extends JavadocTester {
public static void main(String... args) throws Exception {
TestGrandParentTypes tester = new TestGrandParentTypes();
tester.runTests();
}
@Test
void test1() {
javadoc("-d", "out-1",
"-package",
"-sourcepath", testSrc,
"pkg1");
checkExit(Exit.OK);
checkOrder("pkg1/A.SupplierWithAList.html",
"All Superinterfaces:",
"A.AList",
"java.util.Collection&lt;java.lang.Object&gt;",
"java.lang.Iterable&lt;java.lang.Object&gt;",
"java.util.List&lt;java.lang.Object&gt;");
checkOrder("pkg1/A.AList.html",
"All Superinterfaces:",
"java.util.Collection&lt;java.lang.Object&gt;",
"java.lang.Iterable&lt;java.lang.Object&gt;",
"java.util.List&lt;java.lang.Object&gt;");
checkOrder("pkg1/TEnum.html",
"All Implemented Interfaces:",
"java.io.Serializable",
"java.lang.Comparable");
checkOrder("pkg1/TError.html",
"All Implemented Interfaces:",
"java.io.Serializable");
checkOrder("pkg1/TException.html",
"All Implemented Interfaces:",
"java.io.Serializable");
checkOrder("pkg1/MList.html",
"All Implemented Interfaces:",
"java.io.Serializable",
"java.lang.Cloneable",
"java.lang.Iterable&lt;java.lang.String&gt;",
"java.util.Collection&lt;java.lang.String&gt;",
"java.util.List&lt;java.lang.String&gt;",
"java.util.RandomAccess");
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package pkg1;
import java.util.ArrayList;
import java.util.List;
public interface A {
interface AList extends List<Object> { }
interface SupplierWithAList<T> extends AList {
T getThingy();
}
}
enum TEnum {}
class TError extends Error {}
class TException extends Exception {}
class MList extends ArrayList<String> {}