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;
|