/* * Copyright (c) 2014, 2016, 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 * @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 */")); } } catch (Exception e) { addFailure(e); } finally { checkStatus(); } } private void test(String src) { addTestCase(src); printf("Testing test case :\n%s\n", src); try { Map classes = compile(src).getClasses(); String outerClassName = classes.containsKey("deprecated") ? "deprecated" : "notDeprecated"; 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 classes) throws IOException { InnerClassesAttribute innerAttr = cf.findAttribute(Attributes.INNER_CLASSES).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"); } } }