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

     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  */
    26 package com.sun.tools.classfile;
    28 import java.util.ArrayList;
    29 import java.util.List;
    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 {
    41     public Signature(int index) {
    42         super(index);
    43     }
    45     public Type getType(ConstantPool constant_pool) throws ConstantPoolException {
    46         if (type == null)
    47             type = parse(getValue(constant_pool));
    48         return type;
    49     }
    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     }
    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     }
    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     }
    78     @Override
    79     public String getFieldType(ConstantPool constant_pool) throws ConstantPoolException {
    80         return getType(constant_pool).toString();
    81     }
    83     private Type parse(String sig) {
    84         this.sig = sig;
    85         sigp = 0;
    87         List<Type> typeArgTypes = null;
    88         if (sig.charAt(sigp) == '<')
    89             typeArgTypes = parseTypeArgTypes();
    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);
   112         }
   113     }
   115     private Type parseTypeSignature() {
   116         switch (sig.charAt(sigp)) {
   117             case 'B':
   118                 sigp++;
   119                 return new Type.SimpleType("byte");
   121             case 'C':
   122                 sigp++;
   123                 return new Type.SimpleType("char");
   125             case 'D':
   126                 sigp++;
   127                 return new Type.SimpleType("double");
   129             case 'F':
   130                 sigp++;
   131                 return new Type.SimpleType("float");
   133             case 'I':
   134                 sigp++;
   135                 return new Type.SimpleType("int");
   137             case 'J':
   138                 sigp++;
   139                 return new Type.SimpleType("long");
   141             case 'L':
   142                 return parseClassTypeSignature();
   144             case 'S':
   145                 sigp++;
   146                 return new Type.SimpleType("short");
   148             case 'T':
   149                 return parseTypeVariableSignature();
   151             case 'V':
   152                 sigp++;
   153                 return new Type.SimpleType("void");
   155             case 'Z':
   156                 sigp++;
   157                 return new Type.SimpleType("boolean");
   159             case '[':
   160                 sigp++;
   161                 return new Type.ArrayType(parseTypeSignature());
   163             case '*':
   164                 sigp++;
   165                 return new Type.WildcardType();
   167             case '+':
   168                 sigp++;
   169                 return new Type.WildcardType("extends", parseTypeSignature());
   171             case '-':
   172                 sigp++;
   173                 return new Type.WildcardType("super", parseTypeSignature());
   175             default:
   176                 throw new IllegalStateException(debugInfo());
   177         }
   178     }
   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     }
   189     private Type parseClassTypeSignature() {
   190         assert sig.charAt(sigp) == 'L';
   191         sigp++;
   192         return parseClassTypeSignatureRest();
   193     }
   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;
   206                 case '.':
   207                     sigp++;
   208                     if (t == null)
   209                         t = new Type.SimpleType(sb.toString());
   210                     return new Type.InnerClassType(t, parseClassTypeSignatureRest());
   212                 case ';':
   213                     sigp++;
   214                     if (t == null)
   215                         t = new Type.SimpleType(sb.toString());
   216                     return t;
   218                 case '<':
   219                     List<Type> argTypes = parseTypeSignatures('>');
   220                     t = new Type.ClassType(sb.toString(), argTypes);
   221                     break;
   223                 default:
   224                     sigp++;
   225                     sb.append(sigch);
   226                     break;
   227             }
   228         }
   229     }
   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     }
   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     }
   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     }
   267     private String debugInfo() {
   268         return sig.substring(0, sigp) + "!" + sig.charAt(sigp) + "!" + sig.substring(sigp+1);
   269     }
   271     private String sig;
   272     private int sigp;
   274     private Type type;
   275 }

mercurial