8356057: PrintingProcessor (-Xprint) does not print type variable bounds and type annotations for Object supertypes

Reviewed-by: darcy, vromero
This commit is contained in:
Jan Lahoda 2025-05-13 04:44:07 +00:00
parent 4fc10a1e7e
commit 24d77adee9
6 changed files with 241 additions and 21 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2025, 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
@ -259,9 +259,7 @@ public class PrintingProcessor extends AbstractProcessor {
if (kind == CLASS) {
TypeMirror supertype = e.getSuperclass();
if (supertype.getKind() != TypeKind.NONE) {
TypeElement e2 = (TypeElement)
((DeclaredType) supertype).asElement();
if (e2.getSuperclass().getKind() != TypeKind.NONE)
if (isImportantType(supertype))
writer.print(" extends " + supertype);
}
}
@ -524,13 +522,29 @@ public class PrintingProcessor extends AbstractProcessor {
List<? extends TypeParameterElement> typeParams = e.getTypeParameters();
if (!typeParams.isEmpty()) {
writer.print(typeParams.stream()
.map(tpe -> annotationsToString(tpe) + tpe.toString())
.map(tpe -> annotationsToString(tpe) + tpe.toString() + printTypeVariableBoundsIfNeeded(tpe))
.collect(Collectors.joining(", ", "<", ">")));
if (pad)
writer.print(" ");
}
}
private String printTypeVariableBoundsIfNeeded(TypeParameterElement tpe) {
List<? extends TypeMirror> printableBounds =
tpe.getBounds()
.stream()
.filter(type -> isImportantType(type))
.toList();
if (printableBounds.isEmpty()) {
return "";
}
return " extends " + printableBounds.stream()
.map(t -> t.toString())
.collect(Collectors.joining(" & "));
}
private String annotationsToString(Element e) {
List<? extends AnnotationMirror> annotations = e.getAnnotationMirrors();
return annotations.isEmpty() ?
@ -770,5 +784,22 @@ public class PrintingProcessor extends AbstractProcessor {
writer.print(spaces[indentation]);
}
/**{@return true if this type is either not {@code java.lang.Object},
* or is annotated, and hence needs to be included in the output,
* even for cases where there's implicit {@code java.lang.Object} type.}
*
* @param type the type to check.
*/
private boolean isImportantType(TypeMirror type) {
if (!type.getAnnotationMirrors().isEmpty()) {
return true;
}
TypeElement e2 = (TypeElement)
((DeclaredType) type).asElement();
if (!e2.getKind().isClass()) {
return true;
}
return e2.getSuperclass().getKind() != TypeKind.NONE;
}
}
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2025, 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.
*/
/*
* @test
* @bug 8356057
* @summary Verify annotated supertypes and type variable bounds are printed properly
* @compile/ref=XprintTypeAnnotationsAndTypeVarBounds.out -Xprint XprintTypeAnnotationsAndTypeVarBounds.java
*/
import java.lang.annotation.*;
class AnnotatedObjectSuperType extends @TA Object {
}
class UnannotatedObjectSuperType extends Object {
}
class TypeVariableWithAnnotation1<@TA T> {
}
class TypeVariableWithAnnotation2<@TA T extends Object> {
}
class TypeVariableWithBound1<T extends @TA Object> {
}
class TypeVariableWithBound2<T extends @TA CharSequence> {
}
class TypeVariableWithBound3<T extends @TA Object & CharSequence> {
}
class TypeVariableWithBound4<T extends Object & @TA CharSequence> {
}
class TypeVariableWithBound5<T extends CharSequence> {
}
class TypeVariableWithBound6<T extends Object & CharSequence> {
}
class TypeVariableWithBoundRecursive<T extends TypeVariableWithBoundRecursive<T>> {
}
class TypeVariableBoundsOnMethods {
public <@TA T> void test1() {}
public <@TA T extends Object> void test2() {}
public <T extends @TA Object> void test3() {}
public <T extends @TA CharSequence> void test4() {}
public <T extends @TA Object & CharSequence> void test5() {}
public <T extends Object & @TA CharSequence> void test6() {}
public <T extends CharSequence> void test7() {}
public <T extends Object & CharSequence> void test8() {}
}
class TypeVariableBoundsOnConstructors {
public <@TA T> TypeVariableBoundsOnConstructors(boolean b) {}
public <@TA T extends Object> TypeVariableBoundsOnConstructors(byte b) {}
public <T extends @TA Object> TypeVariableBoundsOnConstructors(char c) {}
public <T extends @TA CharSequence> TypeVariableBoundsOnConstructors(short s) {}
public <T extends @TA Object & CharSequence> TypeVariableBoundsOnConstructors(int i) {}
public <T extends Object & @TA CharSequence> TypeVariableBoundsOnConstructors(long l) {}
public <T extends CharSequence> TypeVariableBoundsOnConstructors(float f) {}
public <T extends Object & CharSequence> TypeVariableBoundsOnConstructors(double d) {}
}
@Target(ElementType.TYPE_USE)
@interface TA {
}

View File

@ -0,0 +1,99 @@
class AnnotatedObjectSuperType extends java.lang.@TA Object {
AnnotatedObjectSuperType();
}
class UnannotatedObjectSuperType {
UnannotatedObjectSuperType();
}
class TypeVariableWithAnnotation1<@TA T> {
TypeVariableWithAnnotation1();
}
class TypeVariableWithAnnotation2<@TA T> {
TypeVariableWithAnnotation2();
}
class TypeVariableWithBound1<T extends java.lang.@TA Object> {
TypeVariableWithBound1();
}
class TypeVariableWithBound2<T extends java.lang.@TA CharSequence> {
TypeVariableWithBound2();
}
class TypeVariableWithBound3<T extends java.lang.@TA Object & java.lang.CharSequence> {
TypeVariableWithBound3();
}
class TypeVariableWithBound4<T extends java.lang.@TA CharSequence> {
TypeVariableWithBound4();
}
class TypeVariableWithBound5<T extends java.lang.CharSequence> {
TypeVariableWithBound5();
}
class TypeVariableWithBound6<T extends java.lang.CharSequence> {
TypeVariableWithBound6();
}
class TypeVariableWithBoundRecursive<T extends TypeVariableWithBoundRecursive<T>> {
TypeVariableWithBoundRecursive();
}
class TypeVariableBoundsOnMethods {
TypeVariableBoundsOnMethods();
public <@TA T> void test1();
public <@TA T> void test2();
public <T extends java.lang.@TA Object> void test3();
public <T extends java.lang.@TA CharSequence> void test4();
public <T extends java.lang.@TA Object & java.lang.CharSequence> void test5();
public <T extends java.lang.@TA CharSequence> void test6();
public <T extends java.lang.CharSequence> void test7();
public <T extends java.lang.CharSequence> void test8();
}
class TypeVariableBoundsOnConstructors {
public <@TA T> TypeVariableBoundsOnConstructors(boolean b);
public <@TA T> TypeVariableBoundsOnConstructors(byte b);
public <T extends java.lang.@TA Object> TypeVariableBoundsOnConstructors(char c);
public <T extends java.lang.@TA CharSequence> TypeVariableBoundsOnConstructors(short s);
public <T extends java.lang.@TA Object & java.lang.CharSequence> TypeVariableBoundsOnConstructors(int i);
public <T extends java.lang.@TA CharSequence> TypeVariableBoundsOnConstructors(long l);
public <T extends java.lang.CharSequence> TypeVariableBoundsOnConstructors(float f);
public <T extends java.lang.CharSequence> TypeVariableBoundsOnConstructors(double d);
}
@java.lang.annotation.Target({TYPE_USE})
@interface TA {
}

View File

@ -2,7 +2,7 @@ round: 1
round: 2
@java.lang.Deprecated
public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public class GeneratedSource<T extends java.lang.CharSequence> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public GeneratedSource();
@ -12,7 +12,7 @@ public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> im
}
@java.lang.Deprecated
public class GeneratedClass<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public class GeneratedClass<T extends java.lang.CharSequence> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public GeneratedClass();
@ -23,7 +23,7 @@ public class GeneratedClass<T> extends java.util.ArrayList<java.lang.String> imp
round: 3
@java.lang.Deprecated
public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public class GeneratedSource<T extends java.lang.CharSequence> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public GeneratedSource();
@ -33,7 +33,7 @@ public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> im
}
@java.lang.Deprecated
public class GeneratedClass<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public class GeneratedClass<T extends java.lang.CharSequence> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public GeneratedClass();

View File

@ -1,7 +1,7 @@
round: 1
@java.lang.Deprecated
public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public class GeneratedSource<T extends java.lang.CharSequence> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public GeneratedSource();
@ -11,7 +11,7 @@ public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> im
}
@java.lang.Deprecated
public class GeneratedClass<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public class GeneratedClass<T extends java.lang.CharSequence> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public GeneratedClass();
@ -22,7 +22,7 @@ public class GeneratedClass<T> extends java.util.ArrayList<java.lang.String> imp
round: 2
@javax.annotation.processing.SupportedAnnotationTypes({"*"})
public abstract class GeneratedSource<E> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
public abstract class GeneratedSource<E extends java.lang.Number> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
public GeneratedSource();
@ -30,7 +30,7 @@ public abstract class GeneratedSource<E> extends java.util.LinkedList<java.lang.
}
@javax.annotation.processing.SupportedAnnotationTypes({"*"})
public abstract class GeneratedClass<E> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
public abstract class GeneratedClass<E extends java.lang.Number> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
public GeneratedClass();
@ -39,7 +39,7 @@ public abstract class GeneratedClass<E> extends java.util.LinkedList<java.lang.N
round: 3
@javax.annotation.processing.SupportedAnnotationTypes({"*"})
public abstract class GeneratedSource<E> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
public abstract class GeneratedSource<E extends java.lang.Number> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
public GeneratedSource();
@ -47,7 +47,7 @@ public abstract class GeneratedSource<E> extends java.util.LinkedList<java.lang.
}
@javax.annotation.processing.SupportedAnnotationTypes({"*"})
public abstract class GeneratedClass<E> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
public abstract class GeneratedClass<E extends java.lang.Number> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
public GeneratedClass();

View File

@ -1,7 +1,7 @@
round: 1
@javax.annotation.processing.SupportedAnnotationTypes({"*"})
public abstract class GeneratedSource<E> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
public abstract class GeneratedSource<E extends java.lang.Number> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
public GeneratedSource();
@ -9,7 +9,7 @@ public abstract class GeneratedSource<E> extends java.util.LinkedList<java.lang.
}
@javax.annotation.processing.SupportedAnnotationTypes({"*"})
public abstract class GeneratedClass<E> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
public abstract class GeneratedClass<E extends java.lang.Number> extends java.util.LinkedList<java.lang.Number> implements java.lang.Runnable, java.lang.CharSequence {
public GeneratedClass();
@ -18,7 +18,7 @@ public abstract class GeneratedClass<E> extends java.util.LinkedList<java.lang.N
round: 2
@java.lang.Deprecated
public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public class GeneratedSource<T extends java.lang.CharSequence> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public GeneratedSource();
@ -28,7 +28,7 @@ public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> im
}
@java.lang.Deprecated
public class GeneratedClass<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public class GeneratedClass<T extends java.lang.CharSequence> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public GeneratedClass();
@ -39,7 +39,7 @@ public class GeneratedClass<T> extends java.util.ArrayList<java.lang.String> imp
round: 3
@java.lang.Deprecated
public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public class GeneratedSource<T extends java.lang.CharSequence> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public GeneratedSource();
@ -49,7 +49,7 @@ public class GeneratedSource<T> extends java.util.ArrayList<java.lang.String> im
}
@java.lang.Deprecated
public class GeneratedClass<T> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public class GeneratedClass<T extends java.lang.CharSequence> extends java.util.ArrayList<java.lang.String> implements java.lang.Runnable {
public GeneratedClass();