cfdc64fcb4
Reviewed-by: liach, redestad, vromero
310 lines
14 KiB
Java
310 lines
14 KiB
Java
/*
|
|
* Copyright (c) 2014, 2024, 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 8042261 8298405
|
|
* @summary Checking what attribute is generated by annotation Deprecated
|
|
* or javadoc deprecated for field, method, class(inner/local), interface.
|
|
* @library /tools/lib /tools/javac/lib ../lib
|
|
* @enablePreview
|
|
* @modules jdk.compiler/com.sun.tools.javac.api
|
|
* jdk.compiler/com.sun.tools.javac.main
|
|
* jdk.compiler/com.sun.tools.javac.util
|
|
* java.base/jdk.internal.classfile.impl
|
|
* @build toolbox.ToolBox InMemoryFileManager TestResult TestBase
|
|
* @run main DeprecatedTest
|
|
*/
|
|
|
|
import java.lang.classfile.*;
|
|
import java.lang.classfile.attribute.*;
|
|
import jdk.internal.classfile.impl.BoundAttribute;
|
|
|
|
import javax.tools.JavaFileObject;
|
|
import java.io.IOException;
|
|
import java.util.Map;
|
|
|
|
public class DeprecatedTest extends TestResult {
|
|
|
|
private static final String[] sources = new String[]{
|
|
"@Deprecated public class deprecated {\n"
|
|
+ "@Deprecated class deprecatedInner01 {}\n"
|
|
+ "@Deprecated interface deprecatedInner02 {}\n"
|
|
+ "@Deprecated enum deprecatedInner03 {}\n"
|
|
+ "@Deprecated @interface deprecatedInner04 {}\n"
|
|
+ "class notDeprecatedInner01 {}\n"
|
|
+ "interface notDeprecatedInner02 {}\n"
|
|
+ "enum notDeprecatedInner03 {}\n"
|
|
+ "@interface notDeprecatedInner04 {}\n"
|
|
+ "@Deprecated public void deprecated() {}\n"
|
|
+ "@Deprecated public int deprecated;\n"
|
|
+ "public void notDeprecated() {}\n"
|
|
+ "public int notDeprecated;\n"
|
|
+ "public void f() {\n"
|
|
+ " @Deprecated class deprecatedLocal {\n"
|
|
+ " @Deprecated int deprecated;\n"
|
|
+ " @Deprecated void deprecated() {}\n"
|
|
+ " int notDeprecated;\n"
|
|
+ " void notDeprecated(){}\n"
|
|
+ " }\n"
|
|
+ " class notDeprecatedLocal {\n"
|
|
+ " @Deprecated int deprecated;\n"
|
|
+ " @Deprecated void deprecated() {}\n"
|
|
+ " int notDeprecated;\n"
|
|
+ " void notDeprecated(){}\n"
|
|
+ " }}\n"
|
|
+ "}",
|
|
"@Deprecated public interface deprecated {\n"
|
|
+ "@Deprecated class deprecatedInner01 {}\n"
|
|
+ "@Deprecated interface deprecatedInner02 {}\n"
|
|
+ "@Deprecated enum deprecatedInner03 {}\n"
|
|
+ "@Deprecated @interface deprecatedInner04 {}\n"
|
|
+ "class notDeprecatedInner01 {}\n"
|
|
+ "interface notDeprecatedInner02 {}\n"
|
|
+ "enum notDeprecatedInner03 {}\n"
|
|
+ "@interface notDeprecatedInner04 {}\n"
|
|
+ "@Deprecated void deprecated01();\n"
|
|
+ "void notDeprecated01();\n"
|
|
+ "@Deprecated default void deprecated02() {}\n"
|
|
+ "default void notDeprecated02() {}\n"
|
|
+ "@Deprecated int deprecated = 0;\n"
|
|
+ "int notDeprecated = 0;\n"
|
|
+ "}",
|
|
"@Deprecated public enum deprecated {\n"
|
|
+ "@Deprecated deprecated, notDeprecated;\n"
|
|
+ "@Deprecated class deprecatedInner01 {}\n"
|
|
+ "@Deprecated interface deprecatedInner02 {}\n"
|
|
+ "@Deprecated enum deprecatedInner03 {}\n"
|
|
+ "@Deprecated @interface deprecatedInner04 {}\n"
|
|
+ "class notDeprecatedInner01 {}\n"
|
|
+ "interface notDeprecatedInner02 {}\n"
|
|
+ "enum notDeprecatedInner03 {}\n"
|
|
+ "@interface notDeprecatedInner04 {}\n"
|
|
+ "@Deprecated public void deprecated() {}\n"
|
|
+ "public void notDeprecated() {}\n"
|
|
+ "public void f() {\n"
|
|
+ " @Deprecated class deprecatedLocal {\n"
|
|
+ " @Deprecated int deprecated;\n"
|
|
+ " @Deprecated void deprecated() {}\n"
|
|
+ " int notDeprecated;\n"
|
|
+ " void notDeprecated(){}\n"
|
|
+ " }\n"
|
|
+ " class notDeprecatedLocal {\n"
|
|
+ " @Deprecated int deprecated;\n"
|
|
+ " @Deprecated void deprecated() {}\n"
|
|
+ " int notDeprecated;\n"
|
|
+ " void notDeprecated(){}\n"
|
|
+ " }}\n"
|
|
+ "}",
|
|
"@Deprecated public @interface deprecated {\n"
|
|
+ "@Deprecated class deprecatedInner01 {}\n"
|
|
+ "@Deprecated interface deprecatedInner02 {}\n"
|
|
+ "@Deprecated enum deprecatedInner03 {}\n"
|
|
+ "@Deprecated @interface deprecatedInner04 {}\n"
|
|
+ "class notDeprecatedInner01 {}\n"
|
|
+ "interface notDeprecatedInner02 {}\n"
|
|
+ "enum notDeprecatedInner03 {}\n"
|
|
+ "@interface notDeprecatedInner04 {}\n"
|
|
+ "@Deprecated int deprecated() default 0;\n"
|
|
+ "int notDeprecated() default 0;\n"
|
|
+ "@Deprecated int deprecated = 0;\n"
|
|
+ "int notDeprecated = 0;\n"
|
|
+ "}",
|
|
"public class notDeprecated {\n"
|
|
+ "@Deprecated class deprecatedInner01 {}\n"
|
|
+ "@Deprecated interface deprecatedInner02 {}\n"
|
|
+ "@Deprecated enum deprecatedInner03 {}\n"
|
|
+ "@Deprecated @interface deprecatedInner04 {}\n"
|
|
+ "class notDeprecatedInner01 {}\n"
|
|
+ "interface notDeprecatedInner02 {}\n"
|
|
+ "enum notDeprecatedInner03 {}\n"
|
|
+ "@interface notDeprecatedInner04 {}\n"
|
|
+ "@Deprecated public void deprecated() {}\n"
|
|
+ "@Deprecated public int deprecated;\n"
|
|
+ "public void notDeprecated() {}\n"
|
|
+ "public int notDeprecated;\n"
|
|
+ "public void f() {\n"
|
|
+ " @Deprecated class deprecatedLocal {\n"
|
|
+ " @Deprecated int deprecated;\n"
|
|
+ " @Deprecated void deprecated() {}\n"
|
|
+ " int notDeprecated;\n"
|
|
+ " void notDeprecated(){}\n"
|
|
+ " }\n"
|
|
+ " class notDeprecatedLocal {\n"
|
|
+ " @Deprecated int deprecated;\n"
|
|
+ " @Deprecated void deprecated() {}\n"
|
|
+ " int notDeprecated;\n"
|
|
+ " void notDeprecated(){}\n"
|
|
+ " }}\n"
|
|
+ "}",
|
|
"public interface notDeprecated {\n"
|
|
+ "@Deprecated class deprecatedInner01 {}\n"
|
|
+ "@Deprecated interface deprecatedInner02 {}\n"
|
|
+ "@Deprecated enum deprecatedInner03 {}\n"
|
|
+ "@Deprecated @interface deprecatedInner04 {}\n"
|
|
+ "class notDeprecatedInner01 {}\n"
|
|
+ "interface notDeprecatedInner02 {}\n"
|
|
+ "enum notDeprecatedInner03 {}\n"
|
|
+ "@interface notDeprecatedInner04 {}\n"
|
|
+ "@Deprecated void deprecated01();\n"
|
|
+ "void notDeprecated01();\n"
|
|
+ "@Deprecated default void deprecated02() {}\n"
|
|
+ "default void notDeprecated02() {}\n"
|
|
+ "@Deprecated int deprecated = 0;\n"
|
|
+ "int notDeprecated = 0;\n"
|
|
+ "}",
|
|
"public enum notDeprecated {\n"
|
|
+ "@Deprecated deprecated, notDeprecated;\n"
|
|
+ "@Deprecated class deprecatedInner01 {}\n"
|
|
+ "@Deprecated interface deprecatedInner02 {}\n"
|
|
+ "@Deprecated enum deprecatedInner03 {}\n"
|
|
+ "@Deprecated @interface deprecatedInner04 {}\n"
|
|
+ "class notDeprecatedInner01 {}\n"
|
|
+ "interface notDeprecatedInner02 {}\n"
|
|
+ "enum notDeprecatedInner03 {}\n"
|
|
+ "@interface notDeprecatedInner04 {}\n"
|
|
+ "@Deprecated public void deprecated() {}\n"
|
|
+ "public void notDeprecated() {}\n"
|
|
+ "public void f() {\n"
|
|
+ " @Deprecated class deprecatedLocal {\n"
|
|
+ " @Deprecated int deprecated;\n"
|
|
+ " @Deprecated void deprecated() {}\n"
|
|
+ " int notDeprecated;\n"
|
|
+ " void notDeprecated(){}\n"
|
|
+ " }\n"
|
|
+ " class notDeprecatedLocal {\n"
|
|
+ " @Deprecated int deprecated;\n"
|
|
+ " @Deprecated void deprecated() {}\n"
|
|
+ " int notDeprecated;\n"
|
|
+ " void notDeprecated(){}\n"
|
|
+ " }}\n"
|
|
+ "}",
|
|
"public @interface notDeprecated {\n"
|
|
+ "@Deprecated class deprecatedInner01 {}\n"
|
|
+ "@Deprecated interface deprecatedInner02 {}\n"
|
|
+ "@Deprecated enum deprecatedInner03 {}\n"
|
|
+ "@Deprecated @interface deprecatedInner04 {}\n"
|
|
+ "class notDeprecatedInner01 {}\n"
|
|
+ "interface notDeprecatedInner02 {}\n"
|
|
+ "enum notDeprecatedInner03 {}\n"
|
|
+ "@interface notDeprecatedInner04 {}\n"
|
|
+ "@Deprecated int deprecated() default 0;\n"
|
|
+ "int notDeprecated() default 0;\n"
|
|
+ "@Deprecated int deprecated = 0;\n"
|
|
+ "int notDeprecated = 0;\n"
|
|
+ "}"};
|
|
|
|
public static void main(String[] args) throws TestFailedException {
|
|
new DeprecatedTest().test();
|
|
}
|
|
|
|
public void test() throws TestFailedException {
|
|
try {
|
|
for (String src : sources) {
|
|
test(src);
|
|
test(src.replaceAll("@Deprecated", "/** @deprecated */"));
|
|
test(src.replaceAll("deprecated", "notDeprecated2") // change element name
|
|
.replaceAll("@Deprecated", "/// @deprecated\n"));
|
|
}
|
|
} catch (Exception e) {
|
|
addFailure(e);
|
|
} finally {
|
|
checkStatus();
|
|
}
|
|
}
|
|
|
|
private void test(String src) {
|
|
addTestCase(src);
|
|
printf("Testing test case :\n%s\n", src);
|
|
try {
|
|
Map<String, ? extends JavaFileObject> classes = compile(src).getClasses();
|
|
String outerClassName = classes.keySet().stream()
|
|
.filter(n -> !n.contains("$"))
|
|
.findFirst().orElse(null);
|
|
echo("Testing outer class : " + outerClassName);
|
|
ClassModel cf = readClassFile(classes.get(outerClassName));
|
|
DeprecatedAttribute attr = cf.findAttribute(Attributes.deprecated()).orElse(null);
|
|
testAttribute(outerClassName, attr, cf);
|
|
testInnerClasses(cf, classes);
|
|
testMethods(cf);
|
|
testFields(cf);
|
|
} catch (Exception e) {
|
|
addFailure(e);
|
|
}
|
|
}
|
|
|
|
private void testInnerClasses(ClassModel cf, Map<String, ? extends JavaFileObject> classes)
|
|
throws IOException {
|
|
InnerClassesAttribute innerAttr = cf.findAttribute(Attributes.innerClasses()).orElse(null);
|
|
assert innerAttr != null;
|
|
for (InnerClassInfo innerClass : innerAttr.classes()) {
|
|
String innerClassName = innerClass.innerClass().name().stringValue();
|
|
echo("Testing inner class : " + innerClassName);
|
|
ClassModel innerCf = readClassFile(classes.get(innerClassName));
|
|
DeprecatedAttribute attr = innerCf.findAttribute(Attributes.deprecated()).orElse(null);
|
|
assert innerClass.innerName().isPresent();
|
|
String innerClassSimpleName = innerClass.innerName().get().stringValue();
|
|
testAttribute(innerClassSimpleName, attr, innerCf);
|
|
if (innerClassName.contains("Local")) {
|
|
testMethods(innerCf);
|
|
testFields(innerCf);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void testMethods(ClassModel cf) {
|
|
for (MethodModel m : cf.methods()) {
|
|
String methodName = m.methodName().stringValue();
|
|
echo("Testing method : " + methodName);
|
|
DeprecatedAttribute attr = m.findAttribute(Attributes.deprecated()).orElse(null);
|
|
testAttribute(methodName, attr, cf);
|
|
}
|
|
}
|
|
|
|
private void testFields(ClassModel cm) {
|
|
for (FieldModel f : cm.fields()) {
|
|
String fieldName = f.fieldName().stringValue();
|
|
echo("Testing field : " + fieldName);
|
|
DeprecatedAttribute attr = f.findAttribute(Attributes.deprecated()).orElse(null);
|
|
testAttribute(fieldName, attr, cm);
|
|
}
|
|
}
|
|
|
|
private void testAttribute(String name, DeprecatedAttribute attr, ClassModel cf) {
|
|
if (name.contains("deprecated")) {
|
|
testDeprecatedAttribute(name, attr, cf);
|
|
} else {
|
|
checkNull(attr, name + " should not have deprecated attribute");
|
|
}
|
|
}
|
|
|
|
private void testDeprecatedAttribute(String name, DeprecatedAttribute attr, ClassModel cm) {
|
|
if (checkNotNull(attr, name + " must have deprecated attribute")) {
|
|
checkEquals(0, ((BoundAttribute<?>)attr).payloadLen(),
|
|
"attribute_length should equal to 0");
|
|
checkEquals("Deprecated", attr.attributeName(),
|
|
name + " attribute_name_index");
|
|
}
|
|
}
|
|
}
|