1 /* |
|
2 * Copyright (c) 2007, 2009, 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. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 package com.sun.tools.classfile; |
|
27 |
|
28 import java.io.IOException; |
|
29 |
|
30 /** |
|
31 * See JVMS, section 4.8.16. |
|
32 * |
|
33 * <p><b>This is NOT part of any supported API. |
|
34 * If you write code that depends on this, you do so at your own risk. |
|
35 * This code and its internal interfaces are subject to change or |
|
36 * deletion without notice.</b> |
|
37 */ |
|
38 public class Annotation { |
|
39 static class InvalidAnnotation extends AttributeException { |
|
40 private static final long serialVersionUID = -4620480740735772708L; |
|
41 InvalidAnnotation(String msg) { |
|
42 super(msg); |
|
43 } |
|
44 } |
|
45 |
|
46 Annotation(ClassReader cr) throws IOException, InvalidAnnotation { |
|
47 type_index = cr.readUnsignedShort(); |
|
48 num_element_value_pairs = cr.readUnsignedShort(); |
|
49 element_value_pairs = new element_value_pair[num_element_value_pairs]; |
|
50 for (int i = 0; i < element_value_pairs.length; i++) |
|
51 element_value_pairs[i] = new element_value_pair(cr); |
|
52 } |
|
53 |
|
54 public Annotation(ConstantPool constant_pool, |
|
55 int type_index, |
|
56 element_value_pair[] element_value_pairs) { |
|
57 this.type_index = type_index; |
|
58 num_element_value_pairs = element_value_pairs.length; |
|
59 this.element_value_pairs = element_value_pairs; |
|
60 } |
|
61 |
|
62 public int length() { |
|
63 int n = 2 /*type_index*/ + 2 /*num_element_value_pairs*/; |
|
64 for (element_value_pair pair: element_value_pairs) |
|
65 n += pair.length(); |
|
66 return n; |
|
67 } |
|
68 |
|
69 public final int type_index; |
|
70 public final int num_element_value_pairs; |
|
71 public final element_value_pair element_value_pairs[]; |
|
72 |
|
73 /** |
|
74 * See JVMS, section 4.8.16.1. |
|
75 */ |
|
76 public static abstract class element_value { |
|
77 public static element_value read(ClassReader cr) |
|
78 throws IOException, InvalidAnnotation { |
|
79 int tag = cr.readUnsignedByte(); |
|
80 switch (tag) { |
|
81 case 'B': |
|
82 case 'C': |
|
83 case 'D': |
|
84 case 'F': |
|
85 case 'I': |
|
86 case 'J': |
|
87 case 'S': |
|
88 case 'Z': |
|
89 case 's': |
|
90 return new Primitive_element_value(cr, tag); |
|
91 |
|
92 case 'e': |
|
93 return new Enum_element_value(cr, tag); |
|
94 |
|
95 case 'c': |
|
96 return new Class_element_value(cr, tag); |
|
97 |
|
98 case '@': |
|
99 return new Annotation_element_value(cr, tag); |
|
100 |
|
101 case '[': |
|
102 return new Array_element_value(cr, tag); |
|
103 |
|
104 default: |
|
105 throw new InvalidAnnotation("unrecognized tag: " + tag); |
|
106 } |
|
107 } |
|
108 |
|
109 protected element_value(int tag) { |
|
110 this.tag = tag; |
|
111 } |
|
112 |
|
113 public abstract int length(); |
|
114 |
|
115 public abstract <R,P> R accept(Visitor<R,P> visitor, P p); |
|
116 |
|
117 public interface Visitor<R,P> { |
|
118 R visitPrimitive(Primitive_element_value ev, P p); |
|
119 R visitEnum(Enum_element_value ev, P p); |
|
120 R visitClass(Class_element_value ev, P p); |
|
121 R visitAnnotation(Annotation_element_value ev, P p); |
|
122 R visitArray(Array_element_value ev, P p); |
|
123 } |
|
124 |
|
125 public final int tag; |
|
126 } |
|
127 |
|
128 public static class Primitive_element_value extends element_value { |
|
129 Primitive_element_value(ClassReader cr, int tag) throws IOException { |
|
130 super(tag); |
|
131 const_value_index = cr.readUnsignedShort(); |
|
132 } |
|
133 |
|
134 @Override |
|
135 public int length() { |
|
136 return 2; |
|
137 } |
|
138 |
|
139 public <R,P> R accept(Visitor<R,P> visitor, P p) { |
|
140 return visitor.visitPrimitive(this, p); |
|
141 } |
|
142 |
|
143 public final int const_value_index; |
|
144 |
|
145 } |
|
146 |
|
147 public static class Enum_element_value extends element_value { |
|
148 Enum_element_value(ClassReader cr, int tag) throws IOException { |
|
149 super(tag); |
|
150 type_name_index = cr.readUnsignedShort(); |
|
151 const_name_index = cr.readUnsignedShort(); |
|
152 } |
|
153 |
|
154 @Override |
|
155 public int length() { |
|
156 return 4; |
|
157 } |
|
158 |
|
159 public <R,P> R accept(Visitor<R,P> visitor, P p) { |
|
160 return visitor.visitEnum(this, p); |
|
161 } |
|
162 |
|
163 public final int type_name_index; |
|
164 public final int const_name_index; |
|
165 } |
|
166 |
|
167 public static class Class_element_value extends element_value { |
|
168 Class_element_value(ClassReader cr, int tag) throws IOException { |
|
169 super(tag); |
|
170 class_info_index = cr.readUnsignedShort(); |
|
171 } |
|
172 |
|
173 @Override |
|
174 public int length() { |
|
175 return 2; |
|
176 } |
|
177 |
|
178 public <R,P> R accept(Visitor<R,P> visitor, P p) { |
|
179 return visitor.visitClass(this, p); |
|
180 } |
|
181 |
|
182 public final int class_info_index; |
|
183 } |
|
184 |
|
185 public static class Annotation_element_value extends element_value { |
|
186 Annotation_element_value(ClassReader cr, int tag) |
|
187 throws IOException, InvalidAnnotation { |
|
188 super(tag); |
|
189 annotation_value = new Annotation(cr); |
|
190 } |
|
191 |
|
192 @Override |
|
193 public int length() { |
|
194 return annotation_value.length(); |
|
195 } |
|
196 |
|
197 public <R,P> R accept(Visitor<R,P> visitor, P p) { |
|
198 return visitor.visitAnnotation(this, p); |
|
199 } |
|
200 |
|
201 public final Annotation annotation_value; |
|
202 } |
|
203 |
|
204 public static class Array_element_value extends element_value { |
|
205 Array_element_value(ClassReader cr, int tag) |
|
206 throws IOException, InvalidAnnotation { |
|
207 super(tag); |
|
208 num_values = cr.readUnsignedShort(); |
|
209 values = new element_value[num_values]; |
|
210 for (int i = 0; i < values.length; i++) |
|
211 values[i] = element_value.read(cr); |
|
212 } |
|
213 |
|
214 @Override |
|
215 public int length() { |
|
216 int n = 2; |
|
217 for (int i = 0; i < values.length; i++) |
|
218 n += values[i].length(); |
|
219 return n; |
|
220 } |
|
221 |
|
222 public <R,P> R accept(Visitor<R,P> visitor, P p) { |
|
223 return visitor.visitArray(this, p); |
|
224 } |
|
225 |
|
226 public final int num_values; |
|
227 public final element_value[] values; |
|
228 } |
|
229 |
|
230 public static class element_value_pair { |
|
231 element_value_pair(ClassReader cr) |
|
232 throws IOException, InvalidAnnotation { |
|
233 element_name_index = cr.readUnsignedShort(); |
|
234 value = element_value.read(cr); |
|
235 } |
|
236 |
|
237 public int length() { |
|
238 return 2 + value.length(); |
|
239 } |
|
240 |
|
241 public final int element_name_index; |
|
242 public final element_value value; |
|
243 } |
|
244 } |
|