1. package com.sun.org.apache.bcel.internal.generic;
  2. /* ====================================================================
  3. * The Apache Software License, Version 1.1
  4. *
  5. * Copyright (c) 2001 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Apache" and "Apache Software Foundation" and
  28. * "Apache BCEL" must not be used to endorse or promote products
  29. * derived from this software without prior written permission. For
  30. * written permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * "Apache BCEL", nor may "Apache" appear in their name, without
  34. * prior written permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation. For more
  52. * information on the Apache Software Foundation, please see
  53. * <http://www.apache.org/>.
  54. */
  55. import com.sun.org.apache.bcel.internal.Constants;
  56. import com.sun.org.apache.bcel.internal.classfile.*;
  57. import java.io.*;
  58. import java.util.ArrayList;
  59. /**
  60. * Abstract super class for all possible java types, namely basic types
  61. * such as int, object types like String and array types, e.g. int[]
  62. *
  63. * @version $Id: Type.java,v 1.1.1.1 2001/10/29 20:00:28 jvanzyl Exp $
  64. * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  65. */
  66. public abstract class Type {
  67. protected byte type;
  68. protected String signature; // signature for the type
  69. /** Predefined constants
  70. */
  71. public static final BasicType VOID = new BasicType(Constants.T_VOID);
  72. public static final BasicType BOOLEAN = new BasicType(Constants.T_BOOLEAN);
  73. public static final BasicType INT = new BasicType(Constants.T_INT);
  74. public static final BasicType SHORT = new BasicType(Constants.T_SHORT);
  75. public static final BasicType BYTE = new BasicType(Constants.T_BYTE);
  76. public static final BasicType LONG = new BasicType(Constants.T_LONG);
  77. public static final BasicType DOUBLE = new BasicType(Constants.T_DOUBLE);
  78. public static final BasicType FLOAT = new BasicType(Constants.T_FLOAT);
  79. public static final BasicType CHAR = new BasicType(Constants.T_CHAR);
  80. public static final ObjectType OBJECT = new ObjectType("java.lang.Object");
  81. public static final ObjectType STRING = new ObjectType("java.lang.String");
  82. public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer");
  83. public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable");
  84. public static final Type[] NO_ARGS = new Type[0];
  85. public static final ReferenceType NULL = new ReferenceType();
  86. public static final Type UNKNOWN = new Type(Constants.T_UNKNOWN,
  87. "<unknown object>"){};
  88. protected Type(byte t, String s) {
  89. type = t;
  90. signature = s;
  91. }
  92. /**
  93. * @return signature for given type.
  94. */
  95. public String getSignature() { return signature; }
  96. /**
  97. * @return type as defined in Constants
  98. */
  99. public byte getType() { return type; }
  100. /**
  101. * @return stack size of this type (2 for long and double, 0 for void, 1 otherwise)
  102. */
  103. public int getSize() {
  104. switch(type) {
  105. case Constants.T_DOUBLE:
  106. case Constants.T_LONG: return 2;
  107. case Constants.T_VOID: return 0;
  108. default: return 1;
  109. }
  110. }
  111. /**
  112. * @return Type string, e.g. `int[]'
  113. */
  114. public String toString() {
  115. return ((this.equals(Type.NULL) || (type >= Constants.T_UNKNOWN)))? signature :
  116. Utility.signatureToString(signature, false);
  117. }
  118. /**
  119. * Convert type to Java method signature, e.g. int[] f(java.lang.String x)
  120. * becomes (Ljava/lang/String;)[I
  121. *
  122. * @param return_type what the method returns
  123. * @param arg_types what are the argument types
  124. * @return method signature for given type(s).
  125. */
  126. public static String getMethodSignature(Type return_type, Type[] arg_types) {
  127. StringBuffer buf = new StringBuffer("(");
  128. int length = (arg_types == null)? 0 : arg_types.length;
  129. for(int i=0; i < length; i++)
  130. buf.append(arg_types[i].getSignature());
  131. buf.append(')');
  132. buf.append(return_type.getSignature());
  133. return buf.toString();
  134. }
  135. private static int consumed_chars=0; // Remember position in string, see getArgumentTypes
  136. /**
  137. * Convert signature to a Type object.
  138. * @param signature signature string such as Ljava/lang/String;
  139. * @return type object
  140. */
  141. public static final Type getType(String signature)
  142. throws StringIndexOutOfBoundsException
  143. {
  144. byte type = Utility.typeOfSignature(signature);
  145. if(type <= Constants.T_VOID) {
  146. consumed_chars = 1;
  147. return BasicType.getType(type);
  148. } else if(type == Constants.T_ARRAY) {
  149. int dim=0;
  150. do { // Count dimensions
  151. dim++;
  152. } while(signature.charAt(dim) == '[');
  153. // Recurse, but just once, if the signature is ok
  154. Type t = getType(signature.substring(dim));
  155. consumed_chars += dim; // update counter
  156. return new ArrayType(t, dim);
  157. } else { // type == T_REFERENCE
  158. int index = signature.indexOf(';'); // Look for closing `;'
  159. if(index < 0)
  160. throw new ClassFormatError("Invalid signature: " + signature);
  161. consumed_chars = index + 1; // "Lblabla;" `L' and `;' are removed
  162. return new ObjectType(signature.substring(1, index).replace('/', '.'));
  163. }
  164. }
  165. /**
  166. * Convert return value of a method (signature) to a Type object.
  167. *
  168. * @param signature signature string such as (Ljava/lang/String;)V
  169. * @return return type
  170. */
  171. public static Type getReturnType(String signature) {
  172. try {
  173. // Read return type after `)'
  174. int index = signature.lastIndexOf(')') + 1;
  175. return getType(signature.substring(index));
  176. } catch(StringIndexOutOfBoundsException e) { // Should never occur
  177. throw new ClassFormatError("Invalid method signature: " + signature);
  178. }
  179. }
  180. /**
  181. * Convert arguments of a method (signature) to an array of Type objects.
  182. * @param signature signature string such as (Ljava/lang/String;)V
  183. * @return array of argument types
  184. */
  185. public static Type[] getArgumentTypes(String signature) {
  186. ArrayList vec = new ArrayList();
  187. int index;
  188. Type[] types;
  189. try { // Read all declarations between for `(' and `)'
  190. if(signature.charAt(0) != '(')
  191. throw new ClassFormatError("Invalid method signature: " + signature);
  192. index = 1; // current string position
  193. while(signature.charAt(index) != ')') {
  194. vec.add(getType(signature.substring(index)));
  195. index += consumed_chars; // update position
  196. }
  197. } catch(StringIndexOutOfBoundsException e) { // Should never occur
  198. throw new ClassFormatError("Invalid method signature: " + signature);
  199. }
  200. types = new Type[vec.size()];
  201. vec.toArray(types);
  202. return types;
  203. }
  204. }