diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java index 7aca585f37e..72a2b564ec5 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/PrintingProcessor.java @@ -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 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 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 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; + } } } diff --git a/test/langtools/tools/javac/processing/options/XprintTypeAnnotationsAndTypeVarBounds.java b/test/langtools/tools/javac/processing/options/XprintTypeAnnotationsAndTypeVarBounds.java new file mode 100644 index 00000000000..d81724763db --- /dev/null +++ b/test/langtools/tools/javac/processing/options/XprintTypeAnnotationsAndTypeVarBounds.java @@ -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 { +} + +class TypeVariableWithBound2 { +} + +class TypeVariableWithBound3 { +} + +class TypeVariableWithBound4 { +} + +class TypeVariableWithBound5 { +} + +class TypeVariableWithBound6 { +} + +class TypeVariableWithBoundRecursive> { +} + +class TypeVariableBoundsOnMethods { + public <@TA T> void test1() {} + public <@TA T extends Object> void test2() {} + public void test3() {} + public void test4() {} + public void test5() {} + public void test6() {} + public void test7() {} + public void test8() {} +} + +class TypeVariableBoundsOnConstructors { + public <@TA T> TypeVariableBoundsOnConstructors(boolean b) {} + public <@TA T extends Object> TypeVariableBoundsOnConstructors(byte b) {} + public TypeVariableBoundsOnConstructors(char c) {} + public TypeVariableBoundsOnConstructors(short s) {} + public TypeVariableBoundsOnConstructors(int i) {} + public TypeVariableBoundsOnConstructors(long l) {} + public TypeVariableBoundsOnConstructors(float f) {} + public TypeVariableBoundsOnConstructors(double d) {} +} + +@Target(ElementType.TYPE_USE) +@interface TA { +} diff --git a/test/langtools/tools/javac/processing/options/XprintTypeAnnotationsAndTypeVarBounds.out b/test/langtools/tools/javac/processing/options/XprintTypeAnnotationsAndTypeVarBounds.out new file mode 100644 index 00000000000..89c5c8747d0 --- /dev/null +++ b/test/langtools/tools/javac/processing/options/XprintTypeAnnotationsAndTypeVarBounds.out @@ -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 { + + TypeVariableWithBound1(); +} + +class TypeVariableWithBound2 { + + TypeVariableWithBound2(); +} + +class TypeVariableWithBound3 { + + TypeVariableWithBound3(); +} + +class TypeVariableWithBound4 { + + TypeVariableWithBound4(); +} + +class TypeVariableWithBound5 { + + TypeVariableWithBound5(); +} + +class TypeVariableWithBound6 { + + TypeVariableWithBound6(); +} + +class TypeVariableWithBoundRecursive> { + + TypeVariableWithBoundRecursive(); +} + +class TypeVariableBoundsOnMethods { + + TypeVariableBoundsOnMethods(); + + public <@TA T> void test1(); + + public <@TA T> void test2(); + + public void test3(); + + public void test4(); + + public void test5(); + + public void test6(); + + public void test7(); + + public void test8(); +} + +class TypeVariableBoundsOnConstructors { + + public <@TA T> TypeVariableBoundsOnConstructors(boolean b); + + public <@TA T> TypeVariableBoundsOnConstructors(byte b); + + public TypeVariableBoundsOnConstructors(char c); + + public TypeVariableBoundsOnConstructors(short s); + + public TypeVariableBoundsOnConstructors(int i); + + public TypeVariableBoundsOnConstructors(long l); + + public TypeVariableBoundsOnConstructors(float f); + + public TypeVariableBoundsOnConstructors(double d); +} + +@java.lang.annotation.Target({TYPE_USE}) +@interface TA { +} \ No newline at end of file diff --git a/test/langtools/tools/javac/processing/rounds/OverwriteBetweenCompilations_1.out b/test/langtools/tools/javac/processing/rounds/OverwriteBetweenCompilations_1.out index 1840ca9205e..536ccc17754 100644 --- a/test/langtools/tools/javac/processing/rounds/OverwriteBetweenCompilations_1.out +++ b/test/langtools/tools/javac/processing/rounds/OverwriteBetweenCompilations_1.out @@ -2,7 +2,7 @@ round: 1 round: 2 @java.lang.Deprecated -public class GeneratedSource extends java.util.ArrayList implements java.lang.Runnable { +public class GeneratedSource extends java.util.ArrayList implements java.lang.Runnable { public GeneratedSource(); @@ -12,7 +12,7 @@ public class GeneratedSource extends java.util.ArrayList im } @java.lang.Deprecated -public class GeneratedClass extends java.util.ArrayList implements java.lang.Runnable { +public class GeneratedClass extends java.util.ArrayList implements java.lang.Runnable { public GeneratedClass(); @@ -23,7 +23,7 @@ public class GeneratedClass extends java.util.ArrayList imp round: 3 @java.lang.Deprecated -public class GeneratedSource extends java.util.ArrayList implements java.lang.Runnable { +public class GeneratedSource extends java.util.ArrayList implements java.lang.Runnable { public GeneratedSource(); @@ -33,7 +33,7 @@ public class GeneratedSource extends java.util.ArrayList im } @java.lang.Deprecated -public class GeneratedClass extends java.util.ArrayList implements java.lang.Runnable { +public class GeneratedClass extends java.util.ArrayList implements java.lang.Runnable { public GeneratedClass(); diff --git a/test/langtools/tools/javac/processing/rounds/OverwriteBetweenCompilations_2.out b/test/langtools/tools/javac/processing/rounds/OverwriteBetweenCompilations_2.out index d1bf374bb74..826e2b4bcb0 100644 --- a/test/langtools/tools/javac/processing/rounds/OverwriteBetweenCompilations_2.out +++ b/test/langtools/tools/javac/processing/rounds/OverwriteBetweenCompilations_2.out @@ -1,7 +1,7 @@ round: 1 @java.lang.Deprecated -public class GeneratedSource extends java.util.ArrayList implements java.lang.Runnable { +public class GeneratedSource extends java.util.ArrayList implements java.lang.Runnable { public GeneratedSource(); @@ -11,7 +11,7 @@ public class GeneratedSource extends java.util.ArrayList im } @java.lang.Deprecated -public class GeneratedClass extends java.util.ArrayList implements java.lang.Runnable { +public class GeneratedClass extends java.util.ArrayList implements java.lang.Runnable { public GeneratedClass(); @@ -22,7 +22,7 @@ public class GeneratedClass extends java.util.ArrayList imp round: 2 @javax.annotation.processing.SupportedAnnotationTypes({"*"}) -public abstract class GeneratedSource extends java.util.LinkedList implements java.lang.Runnable, java.lang.CharSequence { +public abstract class GeneratedSource extends java.util.LinkedList implements java.lang.Runnable, java.lang.CharSequence { public GeneratedSource(); @@ -30,7 +30,7 @@ public abstract class GeneratedSource extends java.util.LinkedList extends java.util.LinkedList implements java.lang.Runnable, java.lang.CharSequence { +public abstract class GeneratedClass extends java.util.LinkedList implements java.lang.Runnable, java.lang.CharSequence { public GeneratedClass(); @@ -39,7 +39,7 @@ public abstract class GeneratedClass extends java.util.LinkedList extends java.util.LinkedList implements java.lang.Runnable, java.lang.CharSequence { +public abstract class GeneratedSource extends java.util.LinkedList implements java.lang.Runnable, java.lang.CharSequence { public GeneratedSource(); @@ -47,7 +47,7 @@ public abstract class GeneratedSource extends java.util.LinkedList extends java.util.LinkedList implements java.lang.Runnable, java.lang.CharSequence { +public abstract class GeneratedClass extends java.util.LinkedList implements java.lang.Runnable, java.lang.CharSequence { public GeneratedClass(); diff --git a/test/langtools/tools/javac/processing/rounds/OverwriteBetweenCompilations_3.out b/test/langtools/tools/javac/processing/rounds/OverwriteBetweenCompilations_3.out index 39b044ec78a..1831303304a 100644 --- a/test/langtools/tools/javac/processing/rounds/OverwriteBetweenCompilations_3.out +++ b/test/langtools/tools/javac/processing/rounds/OverwriteBetweenCompilations_3.out @@ -1,7 +1,7 @@ round: 1 @javax.annotation.processing.SupportedAnnotationTypes({"*"}) -public abstract class GeneratedSource extends java.util.LinkedList implements java.lang.Runnable, java.lang.CharSequence { +public abstract class GeneratedSource extends java.util.LinkedList implements java.lang.Runnable, java.lang.CharSequence { public GeneratedSource(); @@ -9,7 +9,7 @@ public abstract class GeneratedSource extends java.util.LinkedList extends java.util.LinkedList implements java.lang.Runnable, java.lang.CharSequence { +public abstract class GeneratedClass extends java.util.LinkedList implements java.lang.Runnable, java.lang.CharSequence { public GeneratedClass(); @@ -18,7 +18,7 @@ public abstract class GeneratedClass extends java.util.LinkedList extends java.util.ArrayList implements java.lang.Runnable { +public class GeneratedSource extends java.util.ArrayList implements java.lang.Runnable { public GeneratedSource(); @@ -28,7 +28,7 @@ public class GeneratedSource extends java.util.ArrayList im } @java.lang.Deprecated -public class GeneratedClass extends java.util.ArrayList implements java.lang.Runnable { +public class GeneratedClass extends java.util.ArrayList implements java.lang.Runnable { public GeneratedClass(); @@ -39,7 +39,7 @@ public class GeneratedClass extends java.util.ArrayList imp round: 3 @java.lang.Deprecated -public class GeneratedSource extends java.util.ArrayList implements java.lang.Runnable { +public class GeneratedSource extends java.util.ArrayList implements java.lang.Runnable { public GeneratedSource(); @@ -49,7 +49,7 @@ public class GeneratedSource extends java.util.ArrayList im } @java.lang.Deprecated -public class GeneratedClass extends java.util.ArrayList implements java.lang.Runnable { +public class GeneratedClass extends java.util.ArrayList implements java.lang.Runnable { public GeneratedClass();