Java Code Examples for com.android.dx.rop.type.Type#getBasicType()

The following examples show how to use com.android.dx.rop.type.Type#getBasicType() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Zeroes.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Gets the "zero" (or {@code null}) value for the given type.
 *
 * @param type {@code non-null;} the type in question
 * @return {@code non-null;} its "zero" value
 */
public static Constant zeroFor(Type type) {
    switch (type.getBasicType()) {
        case Type.BT_BOOLEAN: return CstBoolean.VALUE_FALSE;
        case Type.BT_BYTE:    return CstByte.VALUE_0;
        case Type.BT_CHAR:    return CstChar.VALUE_0;
        case Type.BT_DOUBLE:  return CstDouble.VALUE_0;
        case Type.BT_FLOAT:   return CstFloat.VALUE_0;
        case Type.BT_INT:     return CstInteger.VALUE_0;
        case Type.BT_LONG:    return CstLong.VALUE_0;
        case Type.BT_SHORT:   return CstShort.VALUE_0;
        case Type.BT_OBJECT:  return CstKnownNull.THE_ONE;
        default: {
            throw new UnsupportedOperationException("no zero for type: " +
                    type.toHuman());
        }
    }
}
 
Example 2
Source File: Rops.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the appropriate {@code new-array} rop for the given
 * type. The result is a shared instance.
 *
 * @param arrayType {@code non-null;} array type of array being created
 * @return {@code non-null;} an appropriate instance
 */
public static Rop opNewArray(TypeBearer arrayType) {
    Type type = arrayType.getType();
    Type elementType = type.getComponentType();

    switch (elementType.getBasicType()) {
        case Type.BT_INT:     return NEW_ARRAY_INT;
        case Type.BT_LONG:    return NEW_ARRAY_LONG;
        case Type.BT_FLOAT:   return NEW_ARRAY_FLOAT;
        case Type.BT_DOUBLE:  return NEW_ARRAY_DOUBLE;
        case Type.BT_BOOLEAN: return NEW_ARRAY_BOOLEAN;
        case Type.BT_BYTE:    return NEW_ARRAY_BYTE;
        case Type.BT_CHAR:    return NEW_ARRAY_CHAR;
        case Type.BT_SHORT:   return NEW_ARRAY_SHORT;
        case Type.BT_OBJECT: {
            return new Rop(RegOps.NEW_ARRAY, type, StdTypeList.INT,
                    Exceptions.LIST_Error_NegativeArraySizeException,
                    "new-array-object");
        }
    }

    return throwBadType(type);
}
 
Example 3
Source File: CstType.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Returns an instance of this class that represents the wrapper
 * class corresponding to a given primitive type. For example, if
 * given {@link Type#INT}, this method returns the class reference
 * {@code java.lang.Integer}.
 *
 * @param primitiveType {@code non-null;} the primitive type
 * @return {@code non-null;} the corresponding wrapper class
 */
public static CstType forBoxedPrimitiveType(Type primitiveType) {
    switch (primitiveType.getBasicType()) {
        case Type.BT_BOOLEAN: return BOOLEAN;
        case Type.BT_BYTE:    return BYTE;
        case Type.BT_CHAR:    return CHARACTER;
        case Type.BT_DOUBLE:  return DOUBLE;
        case Type.BT_FLOAT:   return FLOAT;
        case Type.BT_INT:     return INTEGER;
        case Type.BT_LONG:    return LONG;
        case Type.BT_SHORT:   return SHORT;
        case Type.BT_VOID:    return VOID;
    }

    throw new IllegalArgumentException("not primitive: " + primitiveType);
}
 
Example 4
Source File: Zeroes.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Gets the "zero" (or {@code null}) value for the given type.
 *
 * @param type {@code non-null;} the type in question
 * @return {@code non-null;} its "zero" value
 */
public static Constant zeroFor(Type type) {
    switch (type.getBasicType()) {
        case Type.BT_BOOLEAN: return CstBoolean.VALUE_FALSE;
        case Type.BT_BYTE:    return CstByte.VALUE_0;
        case Type.BT_CHAR:    return CstChar.VALUE_0;
        case Type.BT_DOUBLE:  return CstDouble.VALUE_0;
        case Type.BT_FLOAT:   return CstFloat.VALUE_0;
        case Type.BT_INT:     return CstInteger.VALUE_0;
        case Type.BT_LONG:    return CstLong.VALUE_0;
        case Type.BT_SHORT:   return CstShort.VALUE_0;
        case Type.BT_OBJECT:  return CstKnownNull.THE_ONE;
        default: {
            throw new UnsupportedOperationException("no zero for type: " +
                    type.toHuman());
        }
    }
}
 
Example 5
Source File: CstType.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Returns an instance of this class that represents the wrapper
 * class corresponding to a given primitive type. For example, if
 * given {@link Type#INT}, this method returns the class reference
 * {@code java.lang.Integer}.
 *
 * @param primitiveType {@code non-null;} the primitive type
 * @return {@code non-null;} the corresponding wrapper class
 */
public static CstType forBoxedPrimitiveType(Type primitiveType) {
    switch (primitiveType.getBasicType()) {
        case Type.BT_BOOLEAN: return BOOLEAN;
        case Type.BT_BYTE:    return BYTE;
        case Type.BT_CHAR:    return CHARACTER;
        case Type.BT_DOUBLE:  return DOUBLE;
        case Type.BT_FLOAT:   return FLOAT;
        case Type.BT_INT:     return INTEGER;
        case Type.BT_LONG:    return LONG;
        case Type.BT_SHORT:   return SHORT;
        case Type.BT_VOID:    return VOID;
    }

    throw new IllegalArgumentException("not primitive: " + primitiveType);
}
 
Example 6
Source File: Rops.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the appropriate {@code new-array} rop for the given
 * type. The result is a shared instance.
 *
 * @param arrayType {@code non-null;} array type of array being created
 * @return {@code non-null;} an appropriate instance
 */
public static Rop opNewArray(TypeBearer arrayType) {
    Type type = arrayType.getType();
    Type elementType = type.getComponentType();

    switch (elementType.getBasicType()) {
        case Type.BT_INT:     return NEW_ARRAY_INT;
        case Type.BT_LONG:    return NEW_ARRAY_LONG;
        case Type.BT_FLOAT:   return NEW_ARRAY_FLOAT;
        case Type.BT_DOUBLE:  return NEW_ARRAY_DOUBLE;
        case Type.BT_BOOLEAN: return NEW_ARRAY_BOOLEAN;
        case Type.BT_BYTE:    return NEW_ARRAY_BYTE;
        case Type.BT_CHAR:    return NEW_ARRAY_CHAR;
        case Type.BT_SHORT:   return NEW_ARRAY_SHORT;
        case Type.BT_OBJECT: {
            return new Rop(RegOps.NEW_ARRAY, type, StdTypeList.INT,
                    Exceptions.LIST_Error_NegativeArraySizeException,
                    "new-array-object");
        }
    }

    return throwBadType(type);
}
 
Example 7
Source File: Rops.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the appropriate {@code new-array} rop for the given
 * type. The result is a shared instance.
 *
 * @param arrayType {@code non-null;} array type of array being created
 * @return {@code non-null;} an appropriate instance
 */
public static Rop opNewArray(TypeBearer arrayType) {
    Type type = arrayType.getType();
    Type elementType = type.getComponentType();

    switch (elementType.getBasicType()) {
        case Type.BT_INT:     return NEW_ARRAY_INT;
        case Type.BT_LONG:    return NEW_ARRAY_LONG;
        case Type.BT_FLOAT:   return NEW_ARRAY_FLOAT;
        case Type.BT_DOUBLE:  return NEW_ARRAY_DOUBLE;
        case Type.BT_BOOLEAN: return NEW_ARRAY_BOOLEAN;
        case Type.BT_BYTE:    return NEW_ARRAY_BYTE;
        case Type.BT_CHAR:    return NEW_ARRAY_CHAR;
        case Type.BT_SHORT:   return NEW_ARRAY_SHORT;
        case Type.BT_OBJECT: {
            return new Rop(RegOps.NEW_ARRAY, type, StdTypeList.INT,
                    Exceptions.LIST_Error_NegativeArraySizeException,
                    "new-array-object");
        }
    }

    return throwBadType(type);
}
 
Example 8
Source File: CstType.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Returns an instance of this class that represents the wrapper
 * class corresponding to a given primitive type. For example, if
 * given {@link Type#INT}, this method returns the class reference
 * {@code java.lang.Integer}.
 *
 * @param primitiveType {@code non-null;} the primitive type
 * @return {@code non-null;} the corresponding wrapper class
 */
public static CstType forBoxedPrimitiveType(Type primitiveType) {
    switch (primitiveType.getBasicType()) {
        case Type.BT_BOOLEAN: return BOOLEAN;
        case Type.BT_BYTE:    return BYTE;
        case Type.BT_CHAR:    return CHARACTER;
        case Type.BT_DOUBLE:  return DOUBLE;
        case Type.BT_FLOAT:   return FLOAT;
        case Type.BT_INT:     return INTEGER;
        case Type.BT_LONG:    return LONG;
        case Type.BT_SHORT:   return SHORT;
        case Type.BT_VOID:    return VOID;
    }

    throw new IllegalArgumentException("not primitive: " + primitiveType);
}
 
Example 9
Source File: Zeroes.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Gets the "zero" (or {@code null}) value for the given type.
 *
 * @param type {@code non-null;} the type in question
 * @return {@code non-null;} its "zero" value
 */
public static Constant zeroFor(Type type) {
    switch (type.getBasicType()) {
        case Type.BT_BOOLEAN: return CstBoolean.VALUE_FALSE;
        case Type.BT_BYTE:    return CstByte.VALUE_0;
        case Type.BT_CHAR:    return CstChar.VALUE_0;
        case Type.BT_DOUBLE:  return CstDouble.VALUE_0;
        case Type.BT_FLOAT:   return CstFloat.VALUE_0;
        case Type.BT_INT:     return CstInteger.VALUE_0;
        case Type.BT_LONG:    return CstLong.VALUE_0;
        case Type.BT_SHORT:   return CstShort.VALUE_0;
        case Type.BT_OBJECT:  return CstKnownNull.THE_ONE;
        default: {
            throw new UnsupportedOperationException("no zero for type: " +
                    type.toHuman());
        }
    }
}
 
Example 10
Source File: Zeroes.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Gets the "zero" (or {@code null}) value for the given type.
 *
 * @param type {@code non-null;} the type in question
 * @return {@code non-null;} its "zero" value
 */
public static Constant zeroFor(Type type) {
    switch (type.getBasicType()) {
        case Type.BT_BOOLEAN: return CstBoolean.VALUE_FALSE;
        case Type.BT_BYTE:    return CstByte.VALUE_0;
        case Type.BT_CHAR:    return CstChar.VALUE_0;
        case Type.BT_DOUBLE:  return CstDouble.VALUE_0;
        case Type.BT_FLOAT:   return CstFloat.VALUE_0;
        case Type.BT_INT:     return CstInteger.VALUE_0;
        case Type.BT_LONG:    return CstLong.VALUE_0;
        case Type.BT_SHORT:   return CstShort.VALUE_0;
        case Type.BT_OBJECT:  return CstKnownNull.THE_ONE;
        default: {
            throw new UnsupportedOperationException("no zero for type: " +
                    type.toHuman());
        }
    }
}
 
Example 11
Source File: Rops.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the appropriate {@code new-array} rop for the given
 * type. The result is a shared instance.
 *
 * @param arrayType {@code non-null;} array type of array being created
 * @return {@code non-null;} an appropriate instance
 */
public static Rop opNewArray(TypeBearer arrayType) {
    Type type = arrayType.getType();
    Type elementType = type.getComponentType();

    switch (elementType.getBasicType()) {
        case Type.BT_INT:     return NEW_ARRAY_INT;
        case Type.BT_LONG:    return NEW_ARRAY_LONG;
        case Type.BT_FLOAT:   return NEW_ARRAY_FLOAT;
        case Type.BT_DOUBLE:  return NEW_ARRAY_DOUBLE;
        case Type.BT_BOOLEAN: return NEW_ARRAY_BOOLEAN;
        case Type.BT_BYTE:    return NEW_ARRAY_BYTE;
        case Type.BT_CHAR:    return NEW_ARRAY_CHAR;
        case Type.BT_SHORT:   return NEW_ARRAY_SHORT;
        case Type.BT_OBJECT: {
            return new Rop(RegOps.NEW_ARRAY, type, StdTypeList.INT,
                    Exceptions.LIST_Error_NegativeArraySizeException,
                    "new-array-object");
        }
    }

    return throwBadType(type);
}
 
Example 12
Source File: CstType.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Returns an instance of this class that represents the wrapper
 * class corresponding to a given primitive type. For example, if
 * given {@link Type#INT}, this method returns the class reference
 * {@code java.lang.Integer}.
 *
 * @param primitiveType {@code non-null;} the primitive type
 * @return {@code non-null;} the corresponding wrapper class
 */
public static CstType forBoxedPrimitiveType(Type primitiveType) {
    switch (primitiveType.getBasicType()) {
        case Type.BT_BOOLEAN: return BOOLEAN;
        case Type.BT_BYTE:    return BYTE;
        case Type.BT_CHAR:    return CHARACTER;
        case Type.BT_DOUBLE:  return DOUBLE;
        case Type.BT_FLOAT:   return FLOAT;
        case Type.BT_INT:     return INTEGER;
        case Type.BT_LONG:    return LONG;
        case Type.BT_SHORT:   return SHORT;
        case Type.BT_VOID:    return VOID;
    }

    throw new IllegalArgumentException("not primitive: " + primitiveType);
}
 
Example 13
Source File: CfTranslator.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Helper for {@link #processFields}, which translates constants into
 * more specific types if necessary.
 *
 * @param constant {@code non-null;} the constant in question
 * @param type {@code non-null;} the desired type
 */
private static TypedConstant coerceConstant(TypedConstant constant,
        Type type) {
    Type constantType = constant.getType();

    if (constantType.equals(type)) {
        return constant;
    }

    switch (type.getBasicType()) {
        case Type.BT_BOOLEAN: {
            return CstBoolean.make(((CstInteger) constant).getValue());
        }
        case Type.BT_BYTE: {
            return CstByte.make(((CstInteger) constant).getValue());
        }
        case Type.BT_CHAR: {
            return CstChar.make(((CstInteger) constant).getValue());
        }
        case Type.BT_SHORT: {
            return CstShort.make(((CstInteger) constant).getValue());
        }
        default: {
            throw new UnsupportedOperationException("can't coerce " +
                    constant + " to " + type);
        }
    }
}
 
Example 14
Source File: CfTranslator.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Helper for {@link #processFields}, which translates constants into
 * more specific types if necessary.
 *
 * @param constant {@code non-null;} the constant in question
 * @param type {@code non-null;} the desired type
 */
private static TypedConstant coerceConstant(TypedConstant constant,
        Type type) {
    Type constantType = constant.getType();

    if (constantType.equals(type)) {
        return constant;
    }

    switch (type.getBasicType()) {
        case Type.BT_BOOLEAN: {
            return CstBoolean.make(((CstInteger) constant).getValue());
        }
        case Type.BT_BYTE: {
            return CstByte.make(((CstInteger) constant).getValue());
        }
        case Type.BT_CHAR: {
            return CstChar.make(((CstInteger) constant).getValue());
        }
        case Type.BT_SHORT: {
            return CstShort.make(((CstInteger) constant).getValue());
        }
        default: {
            throw new UnsupportedOperationException("can't coerce " +
                    constant + " to " + type);
        }
    }
}
 
Example 15
Source File: CfTranslator.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Helper for {@link #processFields}, which translates constants into
 * more specific types if necessary.
 *
 * @param constant {@code non-null;} the constant in question
 * @param type {@code non-null;} the desired type
 */
private static TypedConstant coerceConstant(TypedConstant constant,
        Type type) {
    Type constantType = constant.getType();

    if (constantType.equals(type)) {
        return constant;
    }

    switch (type.getBasicType()) {
        case Type.BT_BOOLEAN: {
            return CstBoolean.make(((CstInteger) constant).getValue());
        }
        case Type.BT_BYTE: {
            return CstByte.make(((CstInteger) constant).getValue());
        }
        case Type.BT_CHAR: {
            return CstChar.make(((CstInteger) constant).getValue());
        }
        case Type.BT_SHORT: {
            return CstShort.make(((CstInteger) constant).getValue());
        }
        default: {
            throw new UnsupportedOperationException("can't coerce " +
                    constant + " to " + type);
        }
    }
}
 
Example 16
Source File: CfTranslator.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Helper for {@link #processFields}, which translates constants into
 * more specific types if necessary.
 *
 * @param constant {@code non-null;} the constant in question
 * @param type {@code non-null;} the desired type
 */
private static TypedConstant coerceConstant(TypedConstant constant,
        Type type) {
    Type constantType = constant.getType();

    if (constantType.equals(type)) {
        return constant;
    }

    switch (type.getBasicType()) {
        case Type.BT_BOOLEAN: {
            return CstBoolean.make(((CstInteger) constant).getValue());
        }
        case Type.BT_BYTE: {
            return CstByte.make(((CstInteger) constant).getValue());
        }
        case Type.BT_CHAR: {
            return CstChar.make(((CstInteger) constant).getValue());
        }
        case Type.BT_SHORT: {
            return CstShort.make(((CstInteger) constant).getValue());
        }
        default: {
            throw new UnsupportedOperationException("can't coerce " +
                    constant + " to " + type);
        }
    }
}
 
Example 17
Source File: Merger.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/**
 * Returns whether the given supertype is possibly assignable from
 * the given subtype. This takes into account primitiveness,
 * int-likeness, known-nullness, and array dimensions, but does
 * not assume anything about class hierarchy other than that the
 * type {@code Object} is the supertype of all reference
 * types and all arrays are assignable to
 * {@code Serializable} and {@code Cloneable}.
 *
 * @param supertypeBearer {@code non-null;} the supertype
 * @param subtypeBearer {@code non-null;} the subtype
 */
public static boolean isPossiblyAssignableFrom(TypeBearer supertypeBearer,
        TypeBearer subtypeBearer) {
    Type supertype = supertypeBearer.getType();
    Type subtype = subtypeBearer.getType();

    if (supertype.equals(subtype)) {
        // Easy out.
        return true;
    }

    int superBt = supertype.getBasicType();
    int subBt = subtype.getBasicType();

    // Treat return types as Object for the purposes of this method.

    if (superBt == Type.BT_ADDR) {
        supertype = Type.OBJECT;
        superBt = Type.BT_OBJECT;
    }

    if (subBt == Type.BT_ADDR) {
        subtype = Type.OBJECT;
        subBt = Type.BT_OBJECT;
    }

    if ((superBt != Type.BT_OBJECT) || (subBt != Type.BT_OBJECT)) {
        /*
         * No two distinct primitive types are assignable in this sense,
         * unless they are both int-like.
         */
        return supertype.isIntlike() && subtype.isIntlike();
    }

    // At this point, we know both types are reference types.

    if (supertype == Type.KNOWN_NULL) {
        /*
         * A known-null supertype is only assignable from another
         * known-null (handled in the easy out at the top of the
         * method).
         */
        return false;
    } else if (subtype == Type.KNOWN_NULL) {
        /*
         * A known-null subtype is in fact assignable to any
         * reference type.
         */
        return true;
    } else if (supertype == Type.OBJECT) {
        /*
         * Object is assignable from any reference type.
         */
        return true;
    } else if (supertype.isArray()) {
        // The supertype is an array type.
        if (! subtype.isArray()) {
            // The subtype isn't an array, and so can't be assignable.
            return false;
        }

        /*
         * Strip off as many matched component types from both
         * types as possible, and check the assignability of the
         * results.
         */
        do {
            supertype = supertype.getComponentType();
            subtype = subtype.getComponentType();
        } while (supertype.isArray() && subtype.isArray());

        return isPossiblyAssignableFrom(supertype, subtype);
    } else if (subtype.isArray()) {
        /*
         * Other than Object (handled above), array types are
         * assignable only to Serializable and Cloneable.
         */
        return (supertype == Type.SERIALIZABLE) ||
            (supertype == Type.CLONEABLE);
    } else {
        /*
         * All other unequal reference types are considered at
         * least possibly assignable.
         */
        return true;
    }
}
 
Example 18
Source File: Merger.java    From buck with Apache License 2.0 4 votes vote down vote up
/**
 * Returns whether the given supertype is possibly assignable from
 * the given subtype. This takes into account primitiveness,
 * int-likeness, known-nullness, and array dimensions, but does
 * not assume anything about class hierarchy other than that the
 * type {@code Object} is the supertype of all reference
 * types and all arrays are assignable to
 * {@code Serializable} and {@code Cloneable}.
 *
 * @param supertypeBearer {@code non-null;} the supertype
 * @param subtypeBearer {@code non-null;} the subtype
 */
public static boolean isPossiblyAssignableFrom(TypeBearer supertypeBearer,
        TypeBearer subtypeBearer) {
    Type supertype = supertypeBearer.getType();
    Type subtype = subtypeBearer.getType();

    if (supertype.equals(subtype)) {
        // Easy out.
        return true;
    }

    int superBt = supertype.getBasicType();
    int subBt = subtype.getBasicType();

    // Treat return types as Object for the purposes of this method.

    if (superBt == Type.BT_ADDR) {
        supertype = Type.OBJECT;
        superBt = Type.BT_OBJECT;
    }

    if (subBt == Type.BT_ADDR) {
        subtype = Type.OBJECT;
        subBt = Type.BT_OBJECT;
    }

    if ((superBt != Type.BT_OBJECT) || (subBt != Type.BT_OBJECT)) {
        /*
         * No two distinct primitive types are assignable in this sense,
         * unless they are both int-like.
         */
        return supertype.isIntlike() && subtype.isIntlike();
    }

    // At this point, we know both types are reference types.

    if (supertype == Type.KNOWN_NULL) {
        /*
         * A known-null supertype is only assignable from another
         * known-null (handled in the easy out at the top of the
         * method).
         */
        return false;
    } else if (subtype == Type.KNOWN_NULL) {
        /*
         * A known-null subtype is in fact assignable to any
         * reference type.
         */
        return true;
    } else if (supertype == Type.OBJECT) {
        /*
         * Object is assignable from any reference type.
         */
        return true;
    } else if (supertype.isArray()) {
        // The supertype is an array type.
        if (! subtype.isArray()) {
            // The subtype isn't an array, and so can't be assignable.
            return false;
        }

        /*
         * Strip off as many matched component types from both
         * types as possible, and check the assignability of the
         * results.
         */
        do {
            supertype = supertype.getComponentType();
            subtype = subtype.getComponentType();
        } while (supertype.isArray() && subtype.isArray());

        return isPossiblyAssignableFrom(supertype, subtype);
    } else if (subtype.isArray()) {
        /*
         * Other than Object (handled above), array types are
         * assignable only to Serializable and Cloneable.
         */
        return (supertype == Type.SERIALIZABLE) ||
            (supertype == Type.CLONEABLE);
    } else {
        /*
         * All other unequal reference types are considered at
         * least possibly assignable.
         */
        return true;
    }
}
 
Example 19
Source File: Merger.java    From Box with Apache License 2.0 4 votes vote down vote up
/**
 * Returns whether the given supertype is possibly assignable from
 * the given subtype. This takes into account primitiveness,
 * int-likeness, known-nullness, and array dimensions, but does
 * not assume anything about class hierarchy other than that the
 * type {@code Object} is the supertype of all reference
 * types and all arrays are assignable to
 * {@code Serializable} and {@code Cloneable}.
 *
 * @param supertypeBearer {@code non-null;} the supertype
 * @param subtypeBearer {@code non-null;} the subtype
 */
public static boolean isPossiblyAssignableFrom(TypeBearer supertypeBearer,
        TypeBearer subtypeBearer) {
    Type supertype = supertypeBearer.getType();
    Type subtype = subtypeBearer.getType();

    if (supertype.equals(subtype)) {
        // Easy out.
        return true;
    }

    int superBt = supertype.getBasicType();
    int subBt = subtype.getBasicType();

    // Treat return types as Object for the purposes of this method.

    if (superBt == Type.BT_ADDR) {
        supertype = Type.OBJECT;
        superBt = Type.BT_OBJECT;
    }

    if (subBt == Type.BT_ADDR) {
        subtype = Type.OBJECT;
        subBt = Type.BT_OBJECT;
    }

    if ((superBt != Type.BT_OBJECT) || (subBt != Type.BT_OBJECT)) {
        /*
         * No two distinct primitive types are assignable in this sense,
         * unless they are both int-like.
         */
        return supertype.isIntlike() && subtype.isIntlike();
    }

    // At this point, we know both types are reference types.

    if (supertype == Type.KNOWN_NULL) {
        /*
         * A known-null supertype is only assignable from another
         * known-null (handled in the easy out at the top of the
         * method).
         */
        return false;
    } else if (subtype == Type.KNOWN_NULL) {
        /*
         * A known-null subtype is in fact assignable to any
         * reference type.
         */
        return true;
    } else if (supertype == Type.OBJECT) {
        /*
         * Object is assignable from any reference type.
         */
        return true;
    } else if (supertype.isArray()) {
        // The supertype is an array type.
        if (! subtype.isArray()) {
            // The subtype isn't an array, and so can't be assignable.
            return false;
        }

        /*
         * Strip off as many matched component types from both
         * types as possible, and check the assignability of the
         * results.
         */
        do {
            supertype = supertype.getComponentType();
            subtype = subtype.getComponentType();
        } while (supertype.isArray() && subtype.isArray());

        return isPossiblyAssignableFrom(supertype, subtype);
    } else if (subtype.isArray()) {
        /*
         * Other than Object (handled above), array types are
         * assignable only to Serializable and Cloneable.
         */
        return (supertype == Type.SERIALIZABLE) ||
            (supertype == Type.CLONEABLE);
    } else {
        /*
         * All other unequal reference types are considered at
         * least possibly assignable.
         */
        return true;
    }
}
 
Example 20
Source File: Merger.java    From Box with Apache License 2.0 4 votes vote down vote up
/**
 * Returns whether the given supertype is possibly assignable from
 * the given subtype. This takes into account primitiveness,
 * int-likeness, known-nullness, and array dimensions, but does
 * not assume anything about class hierarchy other than that the
 * type {@code Object} is the supertype of all reference
 * types and all arrays are assignable to
 * {@code Serializable} and {@code Cloneable}.
 *
 * @param supertypeBearer {@code non-null;} the supertype
 * @param subtypeBearer {@code non-null;} the subtype
 */
public static boolean isPossiblyAssignableFrom(TypeBearer supertypeBearer,
        TypeBearer subtypeBearer) {
    Type supertype = supertypeBearer.getType();
    Type subtype = subtypeBearer.getType();

    if (supertype.equals(subtype)) {
        // Easy out.
        return true;
    }

    int superBt = supertype.getBasicType();
    int subBt = subtype.getBasicType();

    // Treat return types as Object for the purposes of this method.

    if (superBt == Type.BT_ADDR) {
        supertype = Type.OBJECT;
        superBt = Type.BT_OBJECT;
    }

    if (subBt == Type.BT_ADDR) {
        subtype = Type.OBJECT;
        subBt = Type.BT_OBJECT;
    }

    if ((superBt != Type.BT_OBJECT) || (subBt != Type.BT_OBJECT)) {
        /*
         * No two distinct primitive types are assignable in this sense,
         * unless they are both int-like.
         */
        return supertype.isIntlike() && subtype.isIntlike();
    }

    // At this point, we know both types are reference types.

    if (supertype == Type.KNOWN_NULL) {
        /*
         * A known-null supertype is only assignable from another
         * known-null (handled in the easy out at the top of the
         * method).
         */
        return false;
    } else if (subtype == Type.KNOWN_NULL) {
        /*
         * A known-null subtype is in fact assignable to any
         * reference type.
         */
        return true;
    } else if (supertype == Type.OBJECT) {
        /*
         * Object is assignable from any reference type.
         */
        return true;
    } else if (supertype.isArray()) {
        // The supertype is an array type.
        if (! subtype.isArray()) {
            // The subtype isn't an array, and so can't be assignable.
            return false;
        }

        /*
         * Strip off as many matched component types from both
         * types as possible, and check the assignability of the
         * results.
         */
        do {
            supertype = supertype.getComponentType();
            subtype = subtype.getComponentType();
        } while (supertype.isArray() && subtype.isArray());

        return isPossiblyAssignableFrom(supertype, subtype);
    } else if (subtype.isArray()) {
        /*
         * Other than Object (handled above), array types are
         * assignable only to Serializable and Cloneable.
         */
        return (supertype == Type.SERIALIZABLE) ||
            (supertype == Type.CLONEABLE);
    } else {
        /*
         * All other unequal reference types are considered at
         * least possibly assignable.
         */
        return true;
    }
}