/*
 * reserved comment block
 * DO NOT REMOVE OR ALTER!
 */
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.sun.org.apache.bcel.internal.generic;


import com.sun.org.apache.bcel.internal.Constants;
import com.sun.org.apache.bcel.internal.classfile.*;
import java.util.ArrayList;

Abstract super class for all possible java types, namely basic types such as int, object types like String and array types, e.g. int[]
Author: M. Dahm
/** * Abstract super class for all possible java types, namely basic types * such as int, object types like String and array types, e.g. int[] * * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> */
public abstract class Type implements java.io.Serializable { protected byte type; protected String signature; // signature for the type
Predefined constants
/** Predefined constants */
public static final BasicType VOID = new BasicType(Constants.T_VOID); public static final BasicType BOOLEAN = new BasicType(Constants.T_BOOLEAN); public static final BasicType INT = new BasicType(Constants.T_INT); public static final BasicType SHORT = new BasicType(Constants.T_SHORT); public static final BasicType BYTE = new BasicType(Constants.T_BYTE); public static final BasicType LONG = new BasicType(Constants.T_LONG); public static final BasicType DOUBLE = new BasicType(Constants.T_DOUBLE); public static final BasicType FLOAT = new BasicType(Constants.T_FLOAT); public static final BasicType CHAR = new BasicType(Constants.T_CHAR); public static final ObjectType OBJECT = new ObjectType("java.lang.Object"); public static final ObjectType STRING = new ObjectType("java.lang.String"); public static final ObjectType STRINGBUFFER = new ObjectType("java.lang.StringBuffer"); public static final ObjectType THROWABLE = new ObjectType("java.lang.Throwable"); public static final Type[] NO_ARGS = new Type[0]; public static final ReferenceType NULL = new ReferenceType(){}; public static final Type UNKNOWN = new Type(Constants.T_UNKNOWN, "<unknown object>"){}; protected Type(byte t, String s) { type = t; signature = s; }
Returns:signature for given type.
/** * @return signature for given type. */
public String getSignature() { return signature; }
Returns:type as defined in Constants
/** * @return type as defined in Constants */
public byte getType() { return type; }
Returns:stack size of this type (2 for long and double, 0 for void, 1 otherwise)
/** * @return stack size of this type (2 for long and double, 0 for void, 1 otherwise) */
public int getSize() { switch(type) { case Constants.T_DOUBLE: case Constants.T_LONG: return 2; case Constants.T_VOID: return 0; default: return 1; } }
Returns:Type string, e.g. `int[]'
/** * @return Type string, e.g. `int[]' */
public String toString() { return ((this.equals(Type.NULL) || (type >= Constants.T_UNKNOWN)))? signature : Utility.signatureToString(signature, false); }
Convert type to Java method signature, e.g. int[] f(java.lang.String x) becomes (Ljava/lang/String;)[I
Params:
  • return_type – what the method returns
  • arg_types – what are the argument types
Returns:method signature for given type(s).
/** * Convert type to Java method signature, e.g. int[] f(java.lang.String x) * becomes (Ljava/lang/String;)[I * * @param return_type what the method returns * @param arg_types what are the argument types * @return method signature for given type(s). */
public static String getMethodSignature(Type return_type, Type[] arg_types) { StringBuffer buf = new StringBuffer("("); int length = (arg_types == null)? 0 : arg_types.length; for(int i=0; i < length; i++) buf.append(arg_types[i].getSignature()); buf.append(')'); buf.append(return_type.getSignature()); return buf.toString(); } private static int consumed_chars=0; // Remember position in string, see getArgumentTypes
Convert signature to a Type object.
Params:
  • signature – signature string such as Ljava/lang/String;
Returns:type object
/** * Convert signature to a Type object. * @param signature signature string such as Ljava/lang/String; * @return type object */
public static final Type getType(String signature) throws StringIndexOutOfBoundsException { byte type = Utility.typeOfSignature(signature); if(type <= Constants.T_VOID) { consumed_chars = 1; return BasicType.getType(type); } else if(type == Constants.T_ARRAY) { int dim=0; do { // Count dimensions dim++; } while(signature.charAt(dim) == '['); // Recurse, but just once, if the signature is ok Type t = getType(signature.substring(dim)); consumed_chars += dim; // update counter return new ArrayType(t, dim); } else { // type == T_REFERENCE int index = signature.indexOf(';'); // Look for closing `;' if(index < 0) throw new ClassFormatException("Invalid signature: " + signature); consumed_chars = index + 1; // "Lblabla;" `L' and `;' are removed return new ObjectType(signature.substring(1, index).replace('/', '.')); } }
Convert return value of a method (signature) to a Type object.
Params:
  • signature – signature string such as (Ljava/lang/String;)V
Returns:return type
/** * Convert return value of a method (signature) to a Type object. * * @param signature signature string such as (Ljava/lang/String;)V * @return return type */
public static Type getReturnType(String signature) { try { // Read return type after `)' int index = signature.lastIndexOf(')') + 1; return getType(signature.substring(index)); } catch(StringIndexOutOfBoundsException e) { // Should never occur throw new ClassFormatException("Invalid method signature: " + signature); } }
Convert arguments of a method (signature) to an array of Type objects.
Params:
  • signature – signature string such as (Ljava/lang/String;)V
Returns:array of argument types
/** * Convert arguments of a method (signature) to an array of Type objects. * @param signature signature string such as (Ljava/lang/String;)V * @return array of argument types */
public static Type[] getArgumentTypes(String signature) { ArrayList vec = new ArrayList(); int index; Type[] types; try { // Read all declarations between for `(' and `)' if(signature.charAt(0) != '(') throw new ClassFormatException("Invalid method signature: " + signature); index = 1; // current string position while(signature.charAt(index) != ')') { vec.add(getType(signature.substring(index))); index += consumed_chars; // update position } } catch(StringIndexOutOfBoundsException e) { // Should never occur throw new ClassFormatException("Invalid method signature: " + signature); } types = new Type[vec.size()]; vec.toArray(types); return types; }
Convert runtime java.lang.Class to BCEL Type object.
Params:
  • cl – Java class
Returns:corresponding Type object
/** Convert runtime java.lang.Class to BCEL Type object. * @param cl Java class * @return corresponding Type object */
public static Type getType(java.lang.Class cl) { if(cl == null) { throw new IllegalArgumentException("Class must not be null"); } /* That's an amzingly easy case, because getName() returns * the signature. That's what we would have liked anyway. */ if(cl.isArray()) { return getType(cl.getName()); } else if(cl.isPrimitive()) { if(cl == Integer.TYPE) { return INT; } else if(cl == Void.TYPE) { return VOID; } else if(cl == Double.TYPE) { return DOUBLE; } else if(cl == Float.TYPE) { return FLOAT; } else if(cl == Boolean.TYPE) { return BOOLEAN; } else if(cl == Byte.TYPE) { return BYTE; } else if(cl == Short.TYPE) { return SHORT; } else if(cl == Byte.TYPE) { return BYTE; } else if(cl == Long.TYPE) { return LONG; } else if(cl == Character.TYPE) { return CHAR; } else { throw new IllegalStateException("Ooops, what primitive type is " + cl); } } else { // "Real" class return new ObjectType(cl.getName()); } } public static String getSignature(java.lang.reflect.Method meth) { StringBuffer sb = new StringBuffer("("); Class[] params = meth.getParameterTypes(); // avoid clone for(int j = 0; j < params.length; j++) { sb.append(getType(params[j]).getSignature()); } sb.append(")"); sb.append(getType(meth.getReturnType()).getSignature()); return sb.toString(); } }