1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved. 2 * 3 * This program and the accompanying materials are made available under 4 * the terms of the Common Public License v1.0 which accompanies this distribution, 5 * and is available at http://www.eclipse.org/legal/cpl-v10.html 6 * 7 * $Id: Method_info.java,v 1.1.1.1 2004/05/09 16:57:47 vlad_r Exp $ 8 */ 9 package com.vladium.jcd.cls; 10 11 import java.io.IOException; 12 13 import com.vladium.jcd.cls.attribute.*; 14 import com.vladium.jcd.cls.constant.CONSTANT_Utf8_info; 15 import com.vladium.jcd.lib.UDataInputStream; 16 import com.vladium.jcd.lib.UDataOutputStream; 17 18 // ---------------------------------------------------------------------------- 19 /** 20 * Each class method, and each instance initialization method <init>, is described 21 * by a variable-length method_info structure. The structure has the following 22 * format: 23 * <PRE> 24 * method_info { 25 * u2 access_flags; 26 * u2 name_index; 27 * u2 descriptor_index; 28 * u2 attributes_count; 29 * attribute_info attributes[attributes_count]; 30 * } 31 * </PRE> 32 * 33 * The value of the access_flags item is a mask of modifiers used to describe 34 * access permission to and properties of a method or instance initialization method.<P> 35 * 36 * The value of the name_index item must be a valid index into the constant pool 37 * table. The constant pool entry at that index must be a {@link CONSTANT_Utf8_info} 38 * structure representing either one of the special internal method names, either 39 * <init> or <clinit>, or a valid Java method name, stored as a simple 40 * (not fully qualified) name.<P> 41 * 42 * The value of the descriptor_index item must be a valid index into the constant pool 43 * table. The constant pool entry at that index must be a {@link CONSTANT_Utf8_info} 44 * structure representing a valid Java method descriptor.<P> 45 * 46 * Each value of the attributes table must be a variable-length attribute structure. 47 * A method can have any number of optional attributes associated with it. The only 48 * attributes defined by this specification for the attributes table of a method_info 49 * structure are the Code and Exceptions attributes. See {@link CodeAttribute_info} 50 * and {@link ExceptionsAttribute_info}. 51 * 52 * @author (C) 2001, Vlad Roubtsov 53 */ 54 public 55 final class Method_info implements Cloneable, IAccessFlags 56 { 57 // public: ................................................................ 58 59 60 public int m_name_index; 61 public int m_descriptor_index; 62 63 Method_info(int access_flags, int name_index, int descriptor_index, IAttributeCollection attributes)64 public Method_info (int access_flags, int name_index, int descriptor_index, IAttributeCollection attributes) 65 { 66 m_access_flags = access_flags; 67 68 m_name_index = name_index; 69 m_descriptor_index = descriptor_index; 70 71 m_attributes = attributes; 72 } 73 74 Method_info(final IConstantCollection constants, final UDataInputStream bytes)75 public Method_info (final IConstantCollection constants, 76 final UDataInputStream bytes) 77 throws IOException 78 { 79 m_access_flags = bytes.readU2 (); 80 81 m_name_index = bytes.readU2 (); 82 m_descriptor_index = bytes.readU2 (); 83 84 // TODO: put this logic into AttributeCollection 85 86 final int attributes_count = bytes.readU2 (); 87 m_attributes = ElementFactory.newAttributeCollection (attributes_count); 88 89 for (int i = 0; i < attributes_count; ++ i) 90 { 91 final Attribute_info attribute_info = Attribute_info.new_Attribute_info (constants, bytes); 92 93 m_attributes.add (attribute_info); 94 } 95 } 96 97 /** 98 * Returns the method name within the context of 'cls' class definition. 99 * 100 * @param cls class that contains this method 101 * @return method name 102 */ getName(final ClassDef cls)103 public String getName (final ClassDef cls) 104 { 105 return ((CONSTANT_Utf8_info) cls.getConstants ().get (m_name_index)).m_value; 106 } 107 108 /** 109 * Returns the descriptor string for this method within the context of 'cls' 110 * class definition. 111 * 112 * @param cls class that contains this method 113 * @return field typename descriptor 114 */ getDescriptor(final ClassDef cls)115 public String getDescriptor (final ClassDef cls) 116 { 117 return ((CONSTANT_Utf8_info) cls.getConstants ().get (m_descriptor_index)).m_value; 118 } 119 isNative()120 public boolean isNative () 121 { 122 return (m_access_flags & ACC_NATIVE) != 0; 123 } 124 isAbstract()125 public boolean isAbstract () 126 { 127 return (m_access_flags & ACC_ABSTRACT) != 0; 128 } 129 isSynthetic()130 public boolean isSynthetic () 131 { 132 return m_attributes.hasSynthetic (); 133 } 134 isBridge()135 public boolean isBridge () 136 { 137 return ((m_access_flags & ACC_BRIDGE) != 0) || m_attributes.hasBridge (); 138 } 139 140 // IAccessFlags: 141 setAccessFlags(final int flags)142 public final void setAccessFlags (final int flags) 143 { 144 m_access_flags = flags; 145 } 146 getAccessFlags()147 public final int getAccessFlags () 148 { 149 return m_access_flags; 150 } 151 152 getAttributes()153 public IAttributeCollection getAttributes () 154 { 155 return m_attributes; 156 } 157 158 toString()159 public String toString () 160 { 161 StringBuffer s = new StringBuffer (); 162 163 s.append ("method_info: [modifiers: 0x" + Integer.toHexString(m_access_flags) + ", name_index = " + m_name_index + ", descriptor_index = " + m_descriptor_index + "]\n"); 164 for (int i = 0; i < m_attributes.size (); i++) 165 { 166 Attribute_info attribute_info = m_attributes.get (i); 167 168 s.append ("\t[" + i + "] attribute: " + attribute_info + "\n"); 169 } 170 171 return s.toString (); 172 } 173 174 175 // Cloneable: 176 177 /** 178 * Performs a deep copy. 179 */ clone()180 public Object clone () 181 { 182 try 183 { 184 final Method_info _clone = (Method_info) super.clone (); 185 186 // do deep copy: 187 _clone.m_attributes = (IAttributeCollection) m_attributes.clone (); 188 189 return _clone; 190 } 191 catch (CloneNotSupportedException e) 192 { 193 throw new InternalError (e.toString ()); 194 } 195 } 196 197 // IClassFormatOutput: 198 writeInClassFormat(final UDataOutputStream out)199 public void writeInClassFormat (final UDataOutputStream out) throws IOException 200 { 201 out.writeU2 (m_access_flags); 202 203 out.writeU2 (m_name_index); 204 out.writeU2 (m_descriptor_index); 205 206 m_attributes.writeInClassFormat (out); 207 } 208 209 // protected: ............................................................. 210 211 // package: ............................................................... 212 213 // private: ............................................................... 214 215 216 private int m_access_flags; 217 private IAttributeCollection m_attributes; 218 219 } // end of class 220 // ---------------------------------------------------------------------------- 221