Fields Summary |
---|
private static final HashMap | internTablenon-null; intern table mapping string descriptors to instances |
public static final int | BT_VOIDbasic type constant for void |
public static final int | BT_BOOLEANbasic type constant for boolean |
public static final int | BT_BYTEbasic type constant for byte |
public static final int | BT_CHARbasic type constant for char |
public static final int | BT_DOUBLEbasic type constant for double |
public static final int | BT_FLOATbasic type constant for float |
public static final int | BT_INTbasic type constant for int |
public static final int | BT_LONGbasic type constant for long |
public static final int | BT_SHORTbasic type constant for short |
public static final int | BT_OBJECTbasic type constant for Object |
public static final int | BT_ADDRbasic type constant for a return address |
public static final int | BT_COUNTcount of basic type constants |
public static final Type | BOOLEANnon-null; instance representing boolean |
public static final Type | BYTEnon-null; instance representing byte |
public static final Type | CHARnon-null; instance representing char |
public static final Type | DOUBLEnon-null; instance representing double |
public static final Type | FLOATnon-null; instance representing float |
public static final Type | INTnon-null; instance representing int |
public static final Type | LONGnon-null; instance representing long |
public static final Type | SHORTnon-null; instance representing short |
public static final Type | VOIDnon-null; instance representing void |
public static final Type | KNOWN_NULLnon-null; instance representing a known-null |
public static final Type | RETURN_ADDRESSnon-null; instance representing a subroutine return address |
public static final Type | ANNOTATIONnon-null; instance representing
java.lang.annotation.Annotation |
public static final Type | CLASSnon-null; instance representing java.lang.Class |
public static final Type | CLONEABLEnon-null; instance representing java.lang.Cloneable |
public static final Type | OBJECTnon-null; instance representing java.lang.Object |
public static final Type | SERIALIZABLEnon-null; instance representing java.io.Serializable |
public static final Type | STRINGnon-null; instance representing java.lang.String |
public static final Type | THROWABLEnon-null; instance representing java.lang.Throwable |
public static final Type | BOOLEAN_CLASSnon-null; instance representing java.lang.Boolean ; the
suffix on the name helps disambiguate this from the instance
representing a primitive type |
public static final Type | BYTE_CLASSnon-null; instance representing java.lang.Byte ; the
suffix on the name helps disambiguate this from the instance
representing a primitive type |
public static final Type | CHARACTER_CLASSnon-null; instance representing java.lang.Character ; the
suffix on the name helps disambiguate this from the instance
representing a primitive type |
public static final Type | DOUBLE_CLASSnon-null; instance representing java.lang.Double ; the
suffix on the name helps disambiguate this from the instance
representing a primitive type |
public static final Type | FLOAT_CLASSnon-null; instance representing java.lang.Float ; the
suffix on the name helps disambiguate this from the instance
representing a primitive type |
public static final Type | INTEGER_CLASSnon-null; instance representing java.lang.Integer ; the
suffix on the name helps disambiguate this from the instance
representing a primitive type |
public static final Type | LONG_CLASSnon-null; instance representing java.lang.Long ; the
suffix on the name helps disambiguate this from the instance
representing a primitive type |
public static final Type | SHORT_CLASSnon-null; instance representing java.lang.Short ; the
suffix on the name helps disambiguate this from the instance
representing a primitive type |
public static final Type | VOID_CLASSnon-null; instance representing java.lang.Void ; the
suffix on the name helps disambiguate this from the instance
representing a primitive type |
public static final Type | BOOLEAN_ARRAYnon-null; instance representing boolean[] |
public static final Type | BYTE_ARRAYnon-null; instance representing byte[] |
public static final Type | CHAR_ARRAYnon-null; instance representing char[] |
public static final Type | DOUBLE_ARRAYnon-null; instance representing double[] |
public static final Type | FLOAT_ARRAYnon-null; instance representing float[] |
public static final Type | INT_ARRAYnon-null; instance representing int[] |
public static final Type | LONG_ARRAYnon-null; instance representing long[] |
public static final Type | OBJECT_ARRAYnon-null; instance representing Object[] |
public static final Type | SHORT_ARRAYnon-null; instance representing short[] |
private final String | descriptornon-null; field descriptor for the type |
private final int | basicTypebasic type corresponding to this type; one of the
BT_* constants |
private final int | newAt>= -1; for an uninitialized type, bytecode index that this
instance was allocated at; Integer.MAX_VALUE if it
was an incoming uninitialized instance; -1 if this
is an inititialized instance |
private String | classNamenull-ok; the internal-form class name corresponding to this type, if
calculated; only valid if this is a reference type and
additionally not a return address |
private Type | arrayTypenull-ok; the type corresponding to an array of this type, if
calculated |
private Type | componentTypenull-ok; the type corresponding to elements of this type, if
calculated; only valid if this is an array type |
private Type | initializedTypenull-ok; the type corresponding to the initialized version of
this type, if this instance is in fact an uninitialized type |
Methods Summary |
---|
public com.android.dx.rop.type.Type | asUninitialized(int newAt)Returns a new interned instance which is identical to this one, except
it is indicated as uninitialized and allocated at the given bytecode
index. This instance must be an initialized object type.
if (newAt < 0) {
throw new IllegalArgumentException("newAt < 0");
}
if (!isReference()) {
throw new IllegalArgumentException("not a reference type: " +
descriptor);
}
if (isUninitialized()) {
/*
* Dealing with uninitialized types as a starting point is
* a pain, and it's not clear that it'd ever be used, so
* just disallow it.
*/
throw new IllegalArgumentException("already uninitialized: " +
descriptor);
}
/*
* Create a new descriptor that is unique and shouldn't conflict
* with "normal" type descriptors
*/
String newDesc = 'N" + Hex.u2(newAt) + descriptor;
Type result = new Type(newDesc, BT_OBJECT, newAt);
result.initializedType = this;
return putIntern(result);
|
public int | compareTo(com.android.dx.rop.type.Type other){@inheritDoc}
return descriptor.compareTo(other.descriptor);
|
public boolean | equals(java.lang.Object other){@inheritDoc}
if (this == other) {
/*
* Since externally-visible types are interned, this check
* helps weed out some easy cases.
*/
return true;
}
if (!(other instanceof Type)) {
return false;
}
return descriptor.equals(((Type) other).descriptor);
|
public com.android.dx.rop.type.Type | getArrayType()Gets the type corresponding to an array of this type.
if (arrayType == null) {
arrayType = putIntern(new Type('[" + descriptor, BT_OBJECT));
}
return arrayType;
|
public int | getBasicFrameType(){@inheritDoc}
switch (basicType) {
case BT_BOOLEAN:
case BT_BYTE:
case BT_CHAR:
case BT_INT:
case BT_SHORT: {
return BT_INT;
}
}
return basicType;
|
public int | getBasicType(){@inheritDoc}
return basicType;
|
public int | getCategory()Gets the category. Most instances are category 1. long
and double are the only category 2 types.
switch (basicType) {
case BT_LONG:
case BT_DOUBLE: {
return 2;
}
}
return 1;
|
public java.lang.String | getClassName()Gets the name of the class this type corresponds to, in internal
form. This method is only valid if this instance is for a
normal reference type (that is, a reference type and
additionally not a return address).
if (className == null) {
if (!isReference()) {
throw new IllegalArgumentException("not an object type: " +
descriptor);
}
if (descriptor.charAt(0) == '[") {
className = descriptor;
} else {
className = descriptor.substring(1, descriptor.length() - 1);
}
}
return className;
|
public com.android.dx.rop.type.Type | getComponentType()Gets the component type of this type. This method is only valid on
array types.
if (componentType == null) {
if (descriptor.charAt(0) != '[") {
throw new IllegalArgumentException("not an array type: " +
descriptor);
}
componentType = intern(descriptor.substring(1));
}
return componentType;
|
public java.lang.String | getDescriptor()Gets the descriptor.
return descriptor;
|
public com.android.dx.rop.type.Type | getFrameType(){@inheritDoc}
switch (basicType) {
case BT_BOOLEAN:
case BT_BYTE:
case BT_CHAR:
case BT_INT:
case BT_SHORT: {
return INT;
}
}
return this;
|
public com.android.dx.rop.type.Type | getInitializedType()Gets the initialized type corresponding to this instance, but only
if this instance is in fact an uninitialized object type.
if (initializedType == null) {
throw new IllegalArgumentException("initialized type: " +
descriptor);
}
return initializedType;
|
public int | getNewAt()Gets the bytecode index at which this uninitialized type was
allocated. This returns Integer.MAX_VALUE if this
type is an uninitialized incoming parameter (i.e., the
this of an <init> method) or
-1 if this type is in fact initialized.
return newAt;
|
public com.android.dx.rop.type.Type | getType(){@inheritDoc}
return this;
|
public int | hashCode(){@inheritDoc}
return descriptor.hashCode();
|
public static com.android.dx.rop.type.Type | intern(java.lang.String descriptor)Returns the unique instance corresponding to the type with the
given descriptor. See vmspec-2 sec4.3.2 for details on the
field descriptor syntax. This method does not allow
"V" (that is, type void ) as a valid
descriptor.
Type result = internTable.get(descriptor);
if (result != null) {
return result;
}
char firstChar;
try {
firstChar = descriptor.charAt(0);
} catch (IndexOutOfBoundsException ex) {
// Translate the exception.
throw new IllegalArgumentException("descriptor is empty");
} catch (NullPointerException ex) {
// Elucidate the exception.
throw new NullPointerException("descriptor == null");
}
if (firstChar == '[") {
/*
* Recursively strip away array markers to get at the underlying
* type, and build back on to form the result.
*/
result = intern(descriptor.substring(1));
return result.getArrayType();
}
/*
* If the first character isn't '[' and it wasn't found in the
* intern cache, then it had better be the descriptor for a class.
*/
int length = descriptor.length();
if ((firstChar != 'L") ||
(descriptor.charAt(length - 1) != ';")) {
throw new IllegalArgumentException("bad descriptor");
}
/*
* Validate the characters of the class name itself. Note that
* vmspec-2 does not have a coherent definition for valid
* internal-form class names, and the definition here is fairly
* liberal: A name is considered valid as long as it doesn't
* contain any of '[' ';' '.' '(' ')', and it has no more than one
* '/' in a row, and no '/' at either end.
*/
int limit = (length - 1); // Skip the final ';'.
for (int i = 1; i < limit; i++) {
char c = descriptor.charAt(i);
switch (c) {
case '[":
case ';":
case '.":
case '(":
case ')": {
throw new IllegalArgumentException("bad descriptor");
}
case '/": {
if ((i == 1) ||
(i == (length - 1)) ||
(descriptor.charAt(i - 1) == '/")) {
throw new IllegalArgumentException("bad descriptor");
}
break;
}
}
}
result = new Type(descriptor, BT_OBJECT);
return putIntern(result);
|
public static com.android.dx.rop.type.Type | internClassName(java.lang.String name)Returns the unique instance corresponding to the type of the
class with the given name. Calling this method is equivalent to
calling intern(name) if name begins
with "[" and calling intern("L" + name + ";")
in all other cases.
if (name == null) {
throw new NullPointerException("name == null");
}
if (name.startsWith("[")) {
return intern(name);
}
return intern('L" + name + ';");
|
public static com.android.dx.rop.type.Type | internReturnType(java.lang.String descriptor)Returns the unique instance corresponding to the type with the
given descriptor, allowing "V" to return the type
for void . Other than that one caveat, this method
is identical to {@link #intern}.
try {
if (descriptor.equals("V")) {
// This is the one special case where void may be returned.
return VOID;
}
} catch (NullPointerException ex) {
// Elucidate the exception.
throw new NullPointerException("descriptor == null");
}
return intern(descriptor);
|
public boolean | isArray()Gets whether this type is an array type. If this method returns
true , then it is safe to use {@link #getComponentType}
to determine the component type.
return (descriptor.charAt(0) == '[");
|
public boolean | isArrayOrKnownNull()Gets whether this type is an array type or is a known-null, and
hence is compatible with array types.
return isArray() || equals(KNOWN_NULL);
|
public boolean | isCategory1()Returns whether or not this is a category 1 type.
switch (basicType) {
case BT_LONG:
case BT_DOUBLE: {
return false;
}
}
return true;
|
public boolean | isCategory2()Returns whether or not this is a category 2 type.
switch (basicType) {
case BT_LONG:
case BT_DOUBLE: {
return true;
}
}
return false;
|
public boolean | isConstant(){@inheritDoc}
return false;
|
public boolean | isIntlike()Gets whether this type is "intlike." An intlike type is one which, when
placed on a stack or in a local, is automatically converted to an
int .
switch (basicType) {
case BT_BOOLEAN:
case BT_BYTE:
case BT_CHAR:
case BT_INT:
case BT_SHORT: {
return true;
}
}
return false;
|
public boolean | isPrimitive()Gets whether this type is a primitive type. All types are either
primitive or reference types.
switch (basicType) {
case BT_BOOLEAN:
case BT_BYTE:
case BT_CHAR:
case BT_DOUBLE:
case BT_FLOAT:
case BT_INT:
case BT_LONG:
case BT_SHORT:
case BT_VOID: {
return true;
}
}
return false;
|
public boolean | isReference()Gets whether this type is a normal reference type. A normal
reference type is a reference type that is not a return
address. This method is just convenient shorthand for
getBasicType() == Type.BT_OBJECT .
return (basicType == BT_OBJECT);
|
public boolean | isUninitialized()Gets whether this type represents an uninitialized instance. An
uninitialized instance is what one gets back from the new
opcode, and remains uninitialized until a valid constructor is
invoked on it.
return (newAt >= 0);
|
private static com.android.dx.rop.type.Type | putIntern(com.android.dx.rop.type.Type type)Puts the given instance in the intern table if it's not already
there. If a conflicting value is already in the table, then leave it.
Return the interned value.
synchronized (internTable) {
String descriptor = type.getDescriptor();
Type already = internTable.get(descriptor);
if (already != null) {
return already;
}
internTable.put(descriptor, type);
return type;
}
|
public java.lang.String | toHuman(){@inheritDoc}
switch (basicType) {
case BT_VOID: return "void";
case BT_BOOLEAN: return "boolean";
case BT_BYTE: return "byte";
case BT_CHAR: return "char";
case BT_DOUBLE: return "double";
case BT_FLOAT: return "float";
case BT_INT: return "int";
case BT_LONG: return "long";
case BT_SHORT: return "short";
case BT_OBJECT: break;
default: return descriptor;
}
if (isArray()) {
return getComponentType().toHuman() + "[]";
}
// Remove the "L...;" around the type and convert "/" to ".".
return getClassName().replace("/", ".");
|
public java.lang.String | toString(){@inheritDoc}
return descriptor;
|