View Javadoc

    1   /*
    2    * Copyright  2000-2004 The Apache Software Foundation
    3    *
    4    *  Licensed under the Apache License, Version 2.0 (the "License");
    5    *  you may not use this file except in compliance with the License.
    6    *  You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   *  Unless required by applicable law or agreed to in writing, software
    11   *  distributed under the License is distributed on an "AS IS" BASIS,
    12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   *  See the License for the specific language governing permissions and
    14   *  limitations under the License.
    15   *
    16   */
    17  package org.apache.bcel.classfile;
    18
    19  import java.io.DataInputStream;
    20  import java.io.IOException;
    21  import org.apache.bcel.Constants;
    22  import org.apache.bcel.generic.Type;
    23  import org.apache.bcel.util.BCELComparator;
    24
    25  /***
    26   * This class represents the method info structure, i.e., the representation
    27   * for a method in the class. See JVM specification for details.
    28   * A method has access flags, a name, a signature and a number of attributes.
    29   *
    30   * @version $Id: Method.java 386056 2006-03-15 11:31:56Z tcurdt $
    31   * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
    32   */
    33  public final class Method extends FieldOrMethod {
    34
    35      private static BCELComparator _cmp = new BCELComparator() {
    36
    37          public boolean equals( Object o1, Object o2 ) {
    38              Method THIS = (Method) o1;
    39              Method THAT = (Method) o2;
    40              return THIS.getName().equals(THAT.getName())
    41                      && THIS.getSignature().equals(THAT.getSignature());
    42          }
    43
    44
    45          public int hashCode( Object o ) {
    46              Method THIS = (Method) o;
    47              return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
    48          }
    49      };
    50
    51
    52      /***
    53       * Empty constructor, all attributes have to be defined via `setXXX'
    54       * methods. Use at your own risk.
    55       */
    56      public Method() {
    57      }
    58
    59
    60      /***
    61       * Initialize from another object. Note that both objects use the same
    62       * references (shallow copy). Use clone() for a physical copy.
    63       */
    64      public Method(Method c) {
    65          super(c);
    66      }
    67
    68
    69      /***
    70       * Construct object from file stream.
    71       * @param file Input stream
    72       * @throws IOException
    73       * @throws ClassFormatException
    74       */
    75      Method(DataInputStream file, ConstantPool constant_pool) throws IOException,
    76              ClassFormatException {
    77          super(file, constant_pool);
    78      }
    79
    80
    81      /***
    82       * @param access_flags Access rights of method
    83       * @param name_index Points to field name in constant pool
    84       * @param signature_index Points to encoded signature
    85       * @param attributes Collection of attributes
    86       * @param constant_pool Array of constants
    87       */
    88      public Method(int access_flags, int name_index, int signature_index, Attribute[] attributes,
    89              ConstantPool constant_pool) {
    90          super(access_flags, name_index, signature_index, attributes, constant_pool);
    91      }
    92
    93
    94      /***
    95       * Called by objects that are traversing the nodes of the tree implicitely
    96       * defined by the contents of a Java class. I.e., the hierarchy of methods,
    97       * fields, attributes, etc. spawns a tree of objects.
    98       *
    99       * @param v Visitor object
    100      */
    101     public void accept( Visitor v ) {
    102         v.visitMethod(this);
    103     }
    104
    105
    106     /***
    107      * @return Code attribute of method, if any
    108      */
    109     public final Code getCode() {
    110         for (int i = 0; i < attributes_count; i++) {
    111             if (attributes[i] instanceof Code) {
    112                 return (Code) attributes[i];
    113             }
    114         }
    115         return null;
    116     }
    117
    118
    119     /***
    120      * @return ExceptionTable attribute of method, if any, i.e., list all
    121      * exceptions the method may throw not exception handlers!
    122      */
    123     public final ExceptionTable getExceptionTable() {
    124         for (int i = 0; i < attributes_count; i++) {
    125             if (attributes[i] instanceof ExceptionTable) {
    126                 return (ExceptionTable) attributes[i];
    127             }
    128         }
    129         return null;
    130     }
    131
    132
    133     /*** @return LocalVariableTable of code attribute if any, i.e. the call is forwarded
    134      * to the Code atribute.
    135      */
    136     public final LocalVariableTable getLocalVariableTable() {
    137         Code code = getCode();
    138         if (code == null) {
    139             return null;
    140         }
    141         return code.getLocalVariableTable();
    142     }
    143
    144
    145     /*** @return LineNumberTable of code attribute if any, i.e. the call is forwarded
    146      * to the Code atribute.
    147      */
    148     public final LineNumberTable getLineNumberTable() {
    149         Code code = getCode();
    150         if (code == null) {
    151             return null;
    152         }
    153         return code.getLineNumberTable();
    154     }
    155
    156
    157     /***
    158      * Return string representation close to declaration format,
    159      * `public static void main(String[] args) throws IOException', e.g.
    160      *
    161      * @return String representation of the method.
    162      */
    163     public final String toString() {
    164         ConstantUtf8 c;
    165         String name, signature, access; // Short cuts to constant pool
    166         StringBuffer buf;
    167         access = Utility.accessToString(access_flags);
    168         // Get name and signature from constant pool
    169         c = (ConstantUtf8) constant_pool.getConstant(signature_index, Constants.CONSTANT_Utf8);
    170         signature = c.getBytes();
    171         c = (ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8);
    172         name = c.getBytes();
    173         signature = Utility.methodSignatureToString(signature, name, access, true,
    174                 getLocalVariableTable());
    175         buf = new StringBuffer(signature);
    176         for (int i = 0; i < attributes_count; i++) {
    177             Attribute a = attributes[i];
    178             if (!((a instanceof Code) || (a instanceof ExceptionTable))) {
    179                 buf.append(" [").append(a.toString()).append("]");
    180             }
    181         }
    182         ExceptionTable e = getExceptionTable();
    183         if (e != null) {
    184             String str = e.toString();
    185             if (!str.equals("")) {
    186                 buf.append("\n\t\tthrows ").append(str);
    187             }
    188         }
    189         return buf.toString();
    190     }
    191
    192
    193     /***
    194      * @return deep copy of this method
    195      */
    196     public final Method copy( ConstantPool _constant_pool ) {
    197         return (Method) copy_(_constant_pool);
    198     }
    199
    200
    201     /***
    202      * @return return type of method
    203      */
    204     public Type getReturnType() {
    205         return Type.getReturnType(getSignature());
    206     }
    207
    208
    209     /***
    210      * @return array of method argument types
    211      */
    212     public Type[] getArgumentTypes() {
    213         return Type.getArgumentTypes(getSignature());
    214     }
    215
    216
    217     /***
    218      * @return Comparison strategy object
    219      */
    220     public static BCELComparator getComparator() {
    221         return _cmp;
    222     }
    223
    224
    225     /***
    226      * @param comparator Comparison strategy object
    227      */
    228     public static void setComparator( BCELComparator comparator ) {
    229         _cmp = comparator;
    230     }
    231
    232
    233     /***
    234      * Return value as defined by given BCELComparator strategy.
    235      * By default two method objects are said to be equal when
    236      * their names and signatures are equal.
    237      *
    238      * @see java.lang.Object#equals(java.lang.Object)
    239      */
    240     public boolean equals( Object obj ) {
    241         return _cmp.equals(this, obj);
    242     }
    243
    244
    245     /***
    246      * Return value as defined by given BCELComparator strategy.
    247      * By default return the hashcode of the method's name XOR signature.
    248      *
    249      * @see java.lang.Object#hashCode()
    250      */
    251     public int hashCode() {
    252         return _cmp.hashCode(this);
    253     }
    254 }