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

Tue, 03 Jun 2008 13:26:47 -0700

author
jjg
date
Tue, 03 Jun 2008 13:26:47 -0700
changeset 46
7708bd6d800d
child 54
eaf608c64fec
permissions
-rw-r--r--

4075303: Use javap to enquire aboput a specific inner class
4348375: Javap is not internationalized
4459541: "javap -l" shows line numbers as signed short; they should be unsigned
4501660: change diagnostic of -help as 'print this help message and exit'
4776241: unused source file in javap...
4870651: javap should recognize generics, varargs, enum
4876942: javap invoked without args does not print help screen
4880663: javap could output whitespace between class name and opening brace
4975569: javap doesn't print new flag bits
6271787: javap dumps LocalVariableTypeTable attribute in hex, needs to print a table
6305779: javap: support annotations
6439940: Clean up javap implementation
6469569: wrong check of searchpath in JavapEnvironment
6474890: javap does not open .zip files in -classpath
6587786: Javap throws error : "ERROR:Could not find <classname>" for JRE classes
6622215: javap ignores certain relevant access flags
6622216: javap names some attributes incorrectly
6622232: javap gets whitespace confused
6622260: javap prints negative bytes incorrectly in hex
Reviewed-by: ksrini

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

mercurial