JSR175Annotations.java revision 2942:08092deced3f
1/*
2 * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24import java.io.*;
25import com.sun.tools.classfile.*;
26
27/*
28 * @test JSR175Annotations
29 * @bug 6843077
30 * @summary test that only type annotations are recorded as such in classfile
31 * @modules jdk.jdeps/com.sun.tools.classfile
32 */
33
34public class JSR175Annotations {
35    public static void main(String[] args) throws Exception {
36        new JSR175Annotations().run();
37    }
38
39    public void run() throws Exception {
40        File javaFile = writeTestFile();
41        File classFile = compileTestFile(javaFile);
42
43        ClassFile cf = ClassFile.read(classFile);
44        for (Field f : cf.fields) {
45            test(cf, f);
46        }
47        for (Method m: cf.methods) {
48            test(cf, m);
49        }
50
51        countAnnotations();
52
53        if (errors > 0)
54            throw new Exception(errors + " errors found");
55        System.out.println("PASSED");
56    }
57
58    void test(ClassFile cf, Method m) {
59        test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
60        test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
61    }
62
63    void test(ClassFile cf, Field m) {
64        test(cf, m, Attribute.RuntimeVisibleTypeAnnotations, true);
65        test(cf, m, Attribute.RuntimeInvisibleTypeAnnotations, false);
66    }
67
68    // test the result of Attributes.getIndex according to expectations
69    // encoded in the method's name
70    void test(ClassFile cf, Method m, String name, boolean visible) {
71        int index = m.attributes.getIndex(cf.constant_pool, name);
72        if (index != -1) {
73            Attribute attr = m.attributes.get(index);
74            assert attr instanceof RuntimeTypeAnnotations_attribute;
75            RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
76            all += tAttr.annotations.length;
77            if (visible)
78                visibles += tAttr.annotations.length;
79            else
80                invisibles += tAttr.annotations.length;
81        }
82    }
83
84    // test the result of Attributes.getIndex according to expectations
85    // encoded in the method's name
86    void test(ClassFile cf, Field m, String name, boolean visible) {
87        int index = m.attributes.getIndex(cf.constant_pool, name);
88        if (index != -1) {
89            Attribute attr = m.attributes.get(index);
90            assert attr instanceof RuntimeTypeAnnotations_attribute;
91            RuntimeTypeAnnotations_attribute tAttr = (RuntimeTypeAnnotations_attribute)attr;
92            all += tAttr.annotations.length;
93            if (visible)
94                visibles += tAttr.annotations.length;
95            else
96                invisibles += tAttr.annotations.length;
97        }
98    }
99
100    File writeTestFile() throws IOException {
101        File f = new File("Test.java");
102        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
103        out.println("import java.lang.annotation.*;");
104        out.println("abstract class Test { ");
105        out.println("  @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})");
106        out.println("  @Retention(RetentionPolicy.RUNTIME)");
107        out.println("  @interface A { }");
108        out.println("  @A String m;");
109        out.println("  @A String method(@A String a) {");
110        out.println("    return a;");
111        out.println("  }");
112        out.println("}");
113        out.close();
114        return f;
115    }
116
117    File compileTestFile(File f) {
118        int rc = com.sun.tools.javac.Main.compile(new String[] {"-g", f.getPath() });
119        if (rc != 0)
120            throw new Error("compilation failed. rc=" + rc);
121        String path = f.getPath();
122        return new File(path.substring(0, path.length() - 5) + ".class");
123    }
124
125    void countAnnotations() {
126        int expected_visibles = 0, expected_invisibles = 0;
127        int expected_all = expected_visibles + expected_invisibles;
128
129        if (expected_all != all) {
130            errors++;
131            System.err.println("expected " + expected_all
132                    + " annotations but found " + all);
133        }
134
135        if (expected_visibles != visibles) {
136            errors++;
137            System.err.println("expected " + expected_visibles
138                    + " visibles annotations but found " + visibles);
139        }
140
141        if (expected_invisibles != invisibles) {
142            errors++;
143            System.err.println("expected " + expected_invisibles
144                    + " invisibles annotations but found " + invisibles);
145        }
146
147    }
148
149    int errors;
150    int all;
151    int visibles;
152    int invisibles;
153}
154