src/share/classes/com/sun/tools/classfile/Signature.java

changeset 46
7708bd6d800d
child 54
eaf608c64fec
equal deleted inserted replaced
42:f7e64b33d5a4 46:7708bd6d800d
1 /*
2 * Copyright 2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package com.sun.tools.classfile;
27
28 import java.util.ArrayList;
29 import java.util.List;
30
31 /**
32 * See JVMS3 4.4.4.
33 *
34 * <p><b>This is NOT part of any API supported by Sun Microsystems. If
35 * you write code that depends on this, you do so at your own risk.
36 * This code and its internal interfaces are subject to change or
37 * deletion without notice.</b>
38 */
39 public class Signature extends Descriptor {
40
41 public Signature(int index) {
42 super(index);
43 }
44
45 public Type getType(ConstantPool constant_pool) throws ConstantPoolException {
46 if (type == null)
47 type = parse(getValue(constant_pool));
48 return type;
49 }
50
51 @Override
52 public int getParameterCount(ConstantPool constant_pool) throws ConstantPoolException {
53 Type.MethodType m = (Type.MethodType) getType(constant_pool);
54 return m.argTypes.size();
55 }
56
57 @Override
58 public String getParameterTypes(ConstantPool constant_pool) throws ConstantPoolException {
59 Type.MethodType m = (Type.MethodType) getType(constant_pool);
60 StringBuilder sb = new StringBuilder();
61 sb.append("(");
62 String sep = "";
63 for (Type argType: m.argTypes) {
64 sb.append(sep);
65 sb.append(argType);
66 sep = ", ";
67 }
68 sb.append(")");
69 return sb.toString();
70 }
71
72 @Override
73 public String getReturnType(ConstantPool constant_pool) throws ConstantPoolException {
74 Type.MethodType m = (Type.MethodType) getType(constant_pool);
75 return m.returnType.toString();
76 }
77
78 @Override
79 public String getFieldType(ConstantPool constant_pool) throws ConstantPoolException {
80 return getType(constant_pool).toString();
81 }
82
83 private Type parse(String sig) {
84 this.sig = sig;
85 sigp = 0;
86
87 List<Type> typeArgTypes = null;
88 if (sig.charAt(sigp) == '<')
89 typeArgTypes = parseTypeArgTypes();
90
91 if (sig.charAt(sigp) == '(') {
92 List<Type> argTypes = parseTypeSignatures(')');
93 Type returnType = parseTypeSignature();
94 List<Type> throwsTypes = null;
95 while (sigp < sig.length() && sig.charAt(sigp) == '^') {
96 sigp++;
97 if (throwsTypes == null)
98 throwsTypes = new ArrayList<Type>();
99 throwsTypes.add(parseTypeSignature());
100 }
101 return new Type.MethodType(typeArgTypes, argTypes, returnType, throwsTypes);
102 } else {
103 Type t = parseTypeSignature();
104 if (typeArgTypes == null && sigp == sig.length())
105 return t;
106 Type superclass = t;
107 List<Type> superinterfaces = new ArrayList<Type>();
108 while (sigp < sig.length())
109 superinterfaces.add(parseTypeSignature());
110 return new Type.ClassSigType(typeArgTypes, superclass, superinterfaces);
111
112 }
113 }
114
115 private Type parseTypeSignature() {
116 switch (sig.charAt(sigp)) {
117 case 'B':
118 sigp++;
119 return new Type.SimpleType("byte");
120
121 case 'C':
122 sigp++;
123 return new Type.SimpleType("char");
124
125 case 'D':
126 sigp++;
127 return new Type.SimpleType("double");
128
129 case 'F':
130 sigp++;
131 return new Type.SimpleType("float");
132
133 case 'I':
134 sigp++;
135 return new Type.SimpleType("int");
136
137 case 'J':
138 sigp++;
139 return new Type.SimpleType("long");
140
141 case 'L':
142 return parseClassTypeSignature();
143
144 case 'S':
145 sigp++;
146 return new Type.SimpleType("short");
147
148 case 'T':
149 return parseTypeVariableSignature();
150
151 case 'V':
152 sigp++;
153 return new Type.SimpleType("void");
154
155 case 'Z':
156 sigp++;
157 return new Type.SimpleType("boolean");
158
159 case '[':
160 sigp++;
161 return new Type.ArrayType(parseTypeSignature());
162
163 case '*':
164 sigp++;
165 return new Type.WildcardType();
166
167 case '+':
168 sigp++;
169 return new Type.WildcardType("extends", parseTypeSignature());
170
171 case '-':
172 sigp++;
173 return new Type.WildcardType("super", parseTypeSignature());
174
175 default:
176 throw new IllegalStateException(debugInfo());
177 }
178 }
179
180 private List<Type> parseTypeSignatures(char term) {
181 sigp++;
182 List<Type> types = new ArrayList<Type>();
183 while (sig.charAt(sigp) != term)
184 types.add(parseTypeSignature());
185 sigp++;
186 return types;
187 }
188
189 private Type parseClassTypeSignature() {
190 assert sig.charAt(sigp) == 'L';
191 sigp++;
192 return parseClassTypeSignatureRest();
193 }
194
195 private Type parseClassTypeSignatureRest() {
196 StringBuilder sb = new StringBuilder();
197 Type t = null;
198 char sigch;
199 while (true) {
200 switch (sigch = sig.charAt(sigp)) {
201 case '/':
202 sigp++;
203 sb.append(".");
204 break;
205
206 case '.':
207 sigp++;
208 if (t == null)
209 t = new Type.SimpleType(sb.toString());
210 return new Type.InnerClassType(t, parseClassTypeSignatureRest());
211
212 case ';':
213 sigp++;
214 if (t == null)
215 t = new Type.SimpleType(sb.toString());
216 return t;
217
218 case '<':
219 List<Type> argTypes = parseTypeSignatures('>');
220 t = new Type.ClassType(sb.toString(), argTypes);
221 break;
222
223 default:
224 sigp++;
225 sb.append(sigch);
226 break;
227 }
228 }
229 }
230
231 private List<Type> parseTypeArgTypes() {
232 assert sig.charAt(sigp) == '<';
233 sigp++;
234 List<Type> types = null;
235 types = new ArrayList<Type>();
236 while (sig.charAt(sigp) != '>')
237 types.add(parseTypeArgType());
238 sigp++;
239 return types;
240 }
241
242 private Type parseTypeArgType() {
243 int sep = sig.indexOf(":", sigp);
244 String name = sig.substring(sigp, sep);
245 Type classBound = null;
246 List<Type> interfaceBounds = null;
247 sigp = sep + 1;
248 if (sig.charAt(sigp) != ':')
249 classBound = parseTypeSignature();
250 while (sig.charAt(sigp) == ':') {
251 sigp++;
252 if (interfaceBounds == null)
253 interfaceBounds = new ArrayList<Type>();
254 interfaceBounds.add(parseTypeSignature());
255 }
256 return new Type.TypeArgType(name, classBound, interfaceBounds);
257 }
258
259 private Type parseTypeVariableSignature() {
260 sigp++;
261 int sep = sig.indexOf(';', sigp);
262 Type t = new Type.SimpleType(sig.substring(sigp, sep));
263 sigp = sep + 1;
264 return t;
265 }
266
267 private String debugInfo() {
268 return sig.substring(0, sigp) + "!" + sig.charAt(sigp) + "!" + sig.substring(sigp+1);
269 }
270
271 private String sig;
272 private int sigp;
273
274 private Type type;
275 }

mercurial