org.apache.bcel.generic.ArrayType Java Examples

The following examples show how to use org.apache.bcel.generic.ArrayType. 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: BCELifier.java    From commons-bcel with Apache License 2.0 6 votes vote down vote up
static String printType( final String signature ) {
    final Type type = Type.getType(signature);
    final byte t = type.getType();
    if (t <= Const.T_VOID) {
        return "Type." + Const.getTypeName(t).toUpperCase(Locale.ENGLISH);
    } else if (type.toString().equals("java.lang.String")) {
        return "Type.STRING";
    } else if (type.toString().equals("java.lang.Object")) {
        return "Type.OBJECT";
    } else if (type.toString().equals("java.lang.StringBuffer")) {
        return "Type.STRINGBUFFER";
    } else if (type instanceof ArrayType) {
        final ArrayType at = (ArrayType) type;
        return "new ArrayType(" + printType(at.getBasicType()) + ", " + at.getDimensions()
                + ")";
    } else {
        return "new ObjectType(\"" + Utility.signatureToString(signature, false) + "\")";
    }
}
 
Example #2
Source File: GenericUtilities.java    From spotbugs with GNU Lesser General Public License v2.1 6 votes vote down vote up
/**
 * Get the TypeCategory that represents this Object
 *
 * @see GenericUtilities.TypeCategory
 */
public static final TypeCategory getTypeCategory(Type type) {
    if (type instanceof GenericObjectType) {
        return ((GenericObjectType) type).getTypeCategory();
    }

    if (type instanceof ObjectType || type instanceof NullType) {
        return TypeCategory.PLAIN_OBJECT_TYPE;
    }

    if (type instanceof ArrayType) {
        return TypeCategory.ARRAY_TYPE;
    }

    throw new IllegalArgumentException("Not a reference type: " + type);
}
 
Example #3
Source File: Pass3aVerifier.java    From commons-bcel with Apache License 2.0 6 votes vote down vote up
/** Checks if the constraints of operands of the said instruction(s) are satisfied. */
@Override
public void visitANEWARRAY(final ANEWARRAY o) {
    indexValid(o, o.getIndex());
    final Constant c = constantPoolGen.getConstant(o.getIndex());
    if (!    (c instanceof ConstantClass)) {
        constraintViolated(o, "Expecting a CONSTANT_Class operand, but found a '"+c+"'.");
    }
    final Type t = o.getType(constantPoolGen);
    if (t instanceof ArrayType) {
        final int dimensions = ((ArrayType) t).getDimensions();
        if (dimensions > Const.MAX_ARRAY_DIMENSIONS) {
            constraintViolated(o,
                "Not allowed to create an array with more than "+ Const.MAX_ARRAY_DIMENSIONS + " dimensions;"+
                " actual: " + dimensions);
        }
    }
}
 
Example #4
Source File: Pass3aVerifier.java    From commons-bcel with Apache License 2.0 6 votes vote down vote up
/** Checks if the constraints of operands of the said instruction(s) are satisfied. */
@Override
public void visitMULTIANEWARRAY(final MULTIANEWARRAY o) {
    indexValid(o, o.getIndex());
    final Constant c = constantPoolGen.getConstant(o.getIndex());
    if (!    (c instanceof ConstantClass)) {
        constraintViolated(o, "Expecting a CONSTANT_Class operand, but found a '"+c+"'.");
    }
    final int dimensions2create = o.getDimensions();
    if (dimensions2create < 1) {
        constraintViolated(o, "Number of dimensions to create must be greater than zero.");
    }
    final Type t = o.getType(constantPoolGen);
    if (t instanceof ArrayType) {
        final int dimensions = ((ArrayType) t).getDimensions();
        if (dimensions < dimensions2create) {
            constraintViolated(o,
                "Not allowed to create array with more dimensions ('"+dimensions2create+
                "') than the one referenced by the CONSTANT_Class '"+t+"'.");
        }
    }
    else{
        constraintViolated(o, "Expecting a CONSTANT_Class referencing an array type."+
            " [Constraint not found in The Java Virtual Machine Specification, Second Edition, 4.8.1]");
    }
}
 
Example #5
Source File: Pass3aVerifier.java    From commons-bcel with Apache License 2.0 6 votes vote down vote up
/** Checks if the constraints of operands of the said instruction(s) are satisfied. */
@Override
public void visitNEW(final NEW o) {
    indexValid(o, o.getIndex());
    final Constant c = constantPoolGen.getConstant(o.getIndex());
    if (!    (c instanceof ConstantClass)) {
        constraintViolated(o, "Expecting a CONSTANT_Class operand, but found a '"+c+"'.");
    }
    else{
        final ConstantUtf8 cutf8 = (ConstantUtf8) (constantPoolGen.getConstant( ((ConstantClass) c).getNameIndex() ));
        final Type t = Type.getType("L"+cutf8.getBytes()+";");
        if (t instanceof ArrayType) {
            constraintViolated(o, "NEW must not be used to create an array.");
        }
    }

}
 
Example #6
Source File: GenericUtilities.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Get String representation of a Type including Generic information
 */
public static final String getString(Type type) {
    if (type instanceof GenericObjectType) {
        return ((GenericObjectType) type).toString(true);
    } else if (type instanceof ArrayType) {
        return TypeCategory.asString((ArrayType) type);
    } else {
        return type.toString();
    }
}
 
Example #7
Source File: BCELFactory.java    From commons-bcel with Apache License 2.0 5 votes vote down vote up
@Override
public void visitAllocationInstruction( final AllocationInstruction i ) {
    Type type;
    if (i instanceof CPInstruction) {
        type = ((CPInstruction) i).getType(_cp);
    } else {
        type = ((NEWARRAY) i).getType();
    }
    final short opcode = ((Instruction) i).getOpcode();
    int dim = 1;
    switch (opcode) {
        case Const.NEW:
            _out.println("il.append(_factory.createNew(\"" + ((ObjectType) type).getClassName()
                    + "\"));");
            break;
        case Const.MULTIANEWARRAY:
            dim = ((MULTIANEWARRAY) i).getDimensions();
            //$FALL-THROUGH$
        case Const.ANEWARRAY:
        case Const.NEWARRAY:
            if (type instanceof ArrayType) {
                type = ((ArrayType) type).getBasicType();
            }
            _out.println("il.append(_factory.createNewArray(" + BCELifier.printType(type)
                    + ", (short) " + dim + "));");
            break;
        default:
            throw new IllegalArgumentException("Unhandled opcode: " + opcode);
    }
}
 
Example #8
Source File: Subtypes2.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
private ReferenceType computeFirstCommonSuperclassOfReferenceTypes(ReferenceType a, ReferenceType b)
        throws ClassNotFoundException {
    boolean aIsArrayType = (a instanceof ArrayType);
    boolean bIsArrayType = (b instanceof ArrayType);

    if (aIsArrayType && bIsArrayType) {
        // Merging array types - kind of a pain.

        ArrayType aArrType = (ArrayType) a;
        ArrayType bArrType = (ArrayType) b;

        if (aArrType.getDimensions() == bArrType.getDimensions()) {
            return computeFirstCommonSuperclassOfSameDimensionArrays(aArrType, bArrType);
        } else {
            return computeFirstCommonSuperclassOfDifferentDimensionArrays(aArrType, bArrType);
        }
    }

    if (aIsArrayType || bIsArrayType) {
        // One of a and b is an array type, but not both.
        // Common supertype is Object.
        return Type.OBJECT;
    }

    // Neither a nor b is an array type.
    // Find first common supertypes of ObjectTypes.
    return getFirstCommonSuperclass((ObjectType) a, (ObjectType) b);
}
 
Example #9
Source File: Subtypes2.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Get first common supertype of arrays with the same number of dimensions.
 *
 * @param aArrType
 *            an ArrayType
 * @param bArrType
 *            another ArrayType with the same number of dimensions
 * @return first common supertype
 * @throws ClassNotFoundException
 */
private ReferenceType computeFirstCommonSuperclassOfSameDimensionArrays(ArrayType aArrType, ArrayType bArrType)
        throws ClassNotFoundException {
    assert aArrType.getDimensions() == bArrType.getDimensions();

    Type aBaseType = aArrType.getBasicType();
    Type bBaseType = bArrType.getBasicType();
    boolean aBaseIsObjectType = (aBaseType instanceof ObjectType);
    boolean bBaseIsObjectType = (bBaseType instanceof ObjectType);

    if (!aBaseIsObjectType || !bBaseIsObjectType) {
        assert (aBaseType instanceof BasicType) || (bBaseType instanceof BasicType);

        if (aArrType.getDimensions() > 1) {
            // E.g.: first common supertype of int[][] and WHATEVER[][] is
            // Object[]
            return new ArrayType(Type.OBJECT, aArrType.getDimensions() - 1);
        } else {
            assert aArrType.getDimensions() == 1;
            // E.g.: first common supertype type of int[] and WHATEVER[] is
            // Object
            return Type.OBJECT;
        }
    } else {
        assert (aBaseType instanceof ObjectType);
        assert (bBaseType instanceof ObjectType);

        // Base types are both ObjectTypes, and number of dimensions is
        // same.
        // We just need to find the first common supertype of base types
        // and return a new ArrayType using that base type.
        ObjectType firstCommonBaseType = getFirstCommonSuperclass((ObjectType) aBaseType, (ObjectType) bBaseType);
        return new ArrayType(firstCommonBaseType, aArrType.getDimensions());
    }
}
 
Example #10
Source File: Subtypes2.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Get the first common superclass of arrays with different numbers of
 * dimensions.
 *
 * @param aArrType
 *            an ArrayType
 * @param bArrType
 *            another ArrayType
 * @return ReferenceType representing first common superclass
 */
private ReferenceType computeFirstCommonSuperclassOfDifferentDimensionArrays(ArrayType aArrType, ArrayType bArrType) {
    assert aArrType.getDimensions() != bArrType.getDimensions();

    boolean aBaseTypeIsPrimitive = (aArrType.getBasicType() instanceof BasicType);
    boolean bBaseTypeIsPrimitive = (bArrType.getBasicType() instanceof BasicType);

    if (aBaseTypeIsPrimitive || bBaseTypeIsPrimitive) {
        int minDimensions, maxDimensions;
        if (aArrType.getDimensions() < bArrType.getDimensions()) {
            minDimensions = aArrType.getDimensions();
            maxDimensions = bArrType.getDimensions();
        } else {
            minDimensions = bArrType.getDimensions();
            maxDimensions = aArrType.getDimensions();
        }

        if (minDimensions == 1) {
            // One of the types was something like int[].
            // The only possible common supertype is Object.
            return Type.OBJECT;
        } else {
            // Weird case: e.g.,
            // - first common supertype of int[][] and char[][][] is
            // Object[]
            // because f.c.s. of int[] and char[][] is Object
            // - first common supertype of int[][][] and char[][][][][] is
            // Object[][]
            // because f.c.s. of int[] and char[][][] is Object
            return new ArrayType(Type.OBJECT, maxDimensions - minDimensions);
        }
    } else {
        // Both a and b have base types which are ObjectTypes.
        // Since the arrays have different numbers of dimensions, the
        // f.c.s. will have Object as its base type.
        // E.g., f.c.s. of Cat[] and Dog[][] is Object[]
        return new ArrayType(Type.OBJECT, Math.min(aArrType.getDimensions(), bArrType.getDimensions()));
    }
}
 
Example #11
Source File: Subtypes2Test.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
@Override
protected void setUp() throws Exception {
    super.setUp();
    typeSerializable = ObjectTypeFactory.getInstance("java.io.Serializable");
    typeClonable = ObjectTypeFactory.getInstance("java.lang.Cloneable");
    typeObject = ObjectTypeFactory.getInstance(Values.DOTTED_JAVA_LANG_OBJECT);
    typeInteger = ObjectTypeFactory.getInstance("java.lang.Integer");
    typeString = ObjectTypeFactory.getInstance(Values.DOTTED_JAVA_LANG_STRING);
    typeComparable = ObjectTypeFactory.getInstance("java.lang.Comparable");

    typeList = ObjectTypeFactory.getInstance("java.util.List");
    typeCollection = ObjectTypeFactory.getInstance("java.util.Collection");
    typeHashSet = ObjectTypeFactory.getInstance("java.util.HashSet");
    typeArrayClonable = new ArrayType(typeClonable, 1);
    typeArrayComparable = new ArrayType(typeComparable, 1);
    typeArrayObject = new ArrayType(typeObject, 1);
    typeArrayInteger = new ArrayType(typeInteger, 1);
    typeArrayString = new ArrayType(typeString, 1);
    typeArrayArrayObject = new ArrayType(typeObject, 2);
    typeArrayArraySerializable = new ArrayType(typeSerializable, 2);
    typeArrayArrayString = new ArrayType(typeString, 2);
    typeArrayInt = new ArrayType(Type.INT, 1);
    typeArrayArrayInt = new ArrayType(Type.INT, 2);
    typeArrayArrayArrayInt = new ArrayType(Type.INT, 3);
    typeArrayChar = new ArrayType(Type.CHAR, 1);
    typeArrayArrayChar = new ArrayType(Type.CHAR, 2);
    typeArrayArrayArrayChar = new ArrayType(Type.CHAR, 3);
    typeDynamicString = new FindRefComparison.DynamicStringType();
    typeStaticString = new FindRefComparison.StaticStringType();
    typeParameterString = new FindRefComparison.ParameterStringType();
}
 
Example #12
Source File: TransitiveHull.java    From commons-bcel with Apache License 2.0 5 votes vote down vote up
private void checkType(Type type) {
    if (type instanceof ArrayType) {
        type = ((ArrayType) type).getBasicType();
    }

    if (type instanceof ObjectType) {
        add(((ObjectType) type).getClassName());
    }
}
 
Example #13
Source File: TypeAnalysis.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public void initEntryFact(TypeFrame result) {
    // Make the frame valid
    result.setValid();

    int slot = 0;

    // Clear the stack slots in the frame
    result.clearStack();

    // Add local for "this" pointer, if present
    if (!methodGen.isStatic()) {
        result.setValue(slot++, ObjectTypeFactory.getInstance(methodGen.getClassName()));
    }

    // [Added: Support for Generics]
    // Get a parser that reads the generic signature of the method and
    // can be used to get the correct GenericObjectType if an argument
    // has a class type
    Iterator<String> iter = GenericSignatureParser.getGenericSignatureIterator(method);

    // Add locals for parameters.
    // Note that long and double parameters need to be handled
    // specially because they occupy two locals.
    Type[] argumentTypes = methodGen.getArgumentTypes();
    for (Type argType : argumentTypes) {
        // Add special "extra" type for long or double params.
        // These occupy the slot before the "plain" type.
        if (argType.getType() == Const.T_LONG) {
            result.setValue(slot++, TypeFrame.getLongExtraType());
        } else if (argType.getType() == Const.T_DOUBLE) {
            result.setValue(slot++, TypeFrame.getDoubleExtraType());
        }

        // [Added: Support for Generics]
        String s = (iter == null || !iter.hasNext()) ? null : iter.next();
        if (s != null && (argType instanceof ObjectType || argType instanceof ArrayType)
                && !(argType instanceof ExceptionObjectType)) {
            // replace with a generic version of the type
            try {
                Type t = GenericUtilities.getType(s);
                if (t != null) {
                    argType = t;
                }
            } catch (RuntimeException e) {
            } // degrade gracefully
        }

        // Add the plain parameter type.
        result.setValue(slot++, argType);
    }

    // Set remaining locals to BOTTOM; this will cause any
    // uses of them to be flagged
    while (slot < methodGen.getMaxLocals()) {
        result.setValue(slot++, TypeFrame.getBottomType());
    }
}
 
Example #14
Source File: IncompatibleTypes.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
static public @Nonnull IncompatibleTypes getPriorityForAssumingCompatible(Type expectedType, Type actualType, boolean pointerEquality) {
    if (expectedType.equals(actualType)) {
        return SEEMS_OK;
    }

    if (!(expectedType instanceof ReferenceType)) {
        return SEEMS_OK;
    }
    if (!(actualType instanceof ReferenceType)) {
        return SEEMS_OK;
    }

    while (expectedType instanceof ArrayType && actualType instanceof ArrayType) {
        expectedType = ((ArrayType) expectedType).getElementType();
        actualType = ((ArrayType) actualType).getElementType();
    }

    if (expectedType instanceof BasicType ^ actualType instanceof BasicType) {
        return PRIMATIVE_ARRAY_AND_OTHER_ARRAY;
    }
    if (expectedType instanceof BasicType && actualType instanceof BasicType) {
        if (!expectedType.equals(actualType)) {
            return INCOMPATIBLE_PRIMATIVE_ARRAYS;
        } else {
            return SEEMS_OK;
        }
    }
    if (expectedType instanceof ArrayType) {
        return getPriorityForAssumingCompatibleWithArray(actualType);
    }
    if (actualType instanceof ArrayType) {
        return getPriorityForAssumingCompatibleWithArray(expectedType);
    }
    if (expectedType.equals(actualType)) {
        return SEEMS_OK;
    }

    // For now, ignore the case where either reference is not
    // of an object type. (It could be either an array or null.)
    if (!(expectedType instanceof ObjectType) || !(actualType instanceof ObjectType)) {
        return SEEMS_OK;
    }

    return getPriorityForAssumingCompatible((ObjectType) expectedType, (ObjectType) actualType, pointerEquality);
}
 
Example #15
Source File: DontIgnoreResultOfPutIfAbsent.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
private static int getPriorityForBeingMutable(Type type) {
    if (type instanceof ArrayType) {
        return HIGH_PRIORITY;
    } else if (type instanceof ObjectType) {
        UnreadFieldsData unreadFields = AnalysisContext.currentAnalysisContext().getUnreadFieldsData();

        ClassDescriptor cd = DescriptorFactory.getClassDescriptor((ObjectType) type);
        @SlashedClassName
        String className = cd.getClassName();
        if (immutableClassNames.contains(className)) {
            return Priorities.LOW_PRIORITY;
        }

        XClass xClass = AnalysisContext.currentXFactory().getXClass(cd);
        if (xClass == null) {
            return Priorities.IGNORE_PRIORITY;
        }
        ClassDescriptor superclassDescriptor = xClass.getSuperclassDescriptor();
        if (superclassDescriptor != null) {
            @SlashedClassName
            String superClassName = superclassDescriptor.getClassName();
            if ("java/lang/Enum".equals(superClassName)) {
                return Priorities.LOW_PRIORITY;
            }
        }
        boolean hasMutableField = false;
        boolean hasUpdates = false;
        for (XField f : xClass.getXFields()) {
            if (!f.isStatic()) {
                if (!f.isFinal() && !f.isSynthetic()) {
                    hasMutableField = true;
                    if (unreadFields.isWrittenOutsideOfInitialization(f)) {
                        hasUpdates = true;
                    }
                }
                String signature = f.getSignature();
                if (signature.startsWith("Ljava/util/concurrent") || signature.startsWith("Ljava/lang/StringB")
                        || signature.charAt(0) == '[' || signature.indexOf("Map") >= 0 || signature.indexOf("List") >= 0
                        || signature.indexOf("Set") >= 0) {
                    hasMutableField = hasUpdates = true;
                }

            }
        }

        if (!hasMutableField && !xClass.isInterface() && !xClass.isAbstract()) {
            return Priorities.LOW_PRIORITY;
        }
        if (hasUpdates || className.startsWith("java/util") || className.indexOf("Map") >= 0
                || className.indexOf("List") >= 0) {
            return Priorities.HIGH_PRIORITY;
        }
        return Priorities.NORMAL_PRIORITY;

    } else {
        return Priorities.IGNORE_PRIORITY;
    }
}
 
Example #16
Source File: Subtypes2.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Determine whether or not a given ReferenceType is a subtype of another.
 * Throws ClassNotFoundException if the question cannot be answered
 * definitively due to a missing class.
 *
 * @param type
 *            a ReferenceType
 * @param possibleSupertype
 *            another Reference type
 * @return true if <code>type</code> is a subtype of
 *         <code>possibleSupertype</code>, false if not
 * @throws ClassNotFoundException
 *             if a missing class prevents a definitive answer
 */
public boolean isSubtype(ReferenceType type, ReferenceType possibleSupertype) throws ClassNotFoundException {

    // Eliminate some easy cases
    if (type.equals(possibleSupertype)) {
        return true;
    }
    if (possibleSupertype.equals(Type.OBJECT)) {
        return true;
    }
    if (type.equals(Type.OBJECT)) {
        return false;
    }

    boolean typeIsObjectType = (type instanceof ObjectType);
    boolean possibleSupertypeIsObjectType = (possibleSupertype instanceof ObjectType);

    if (typeIsObjectType && possibleSupertypeIsObjectType) {
        // Both types are ordinary object (non-array) types.
        return isSubtype((ObjectType) type, (ObjectType) possibleSupertype);
    }

    boolean typeIsArrayType = (type instanceof ArrayType);
    boolean possibleSupertypeIsArrayType = (possibleSupertype instanceof ArrayType);

    if (typeIsArrayType) {
        // Check superclass/interfaces
        if (possibleSupertype.equals(SERIALIZABLE) || possibleSupertype.equals(CLONEABLE)) {
            return true;
        }

        // We checked all of the possible class/interface supertypes,
        // so if possibleSupertype is not an array type,
        // then we can definitively say no
        if (!possibleSupertypeIsArrayType) {
            return false;
        }

        // Check array/array subtype relationship

        ArrayType typeAsArrayType = (ArrayType) type;
        ArrayType possibleSupertypeAsArrayType = (ArrayType) possibleSupertype;

        // Must have same number of dimensions
        if (typeAsArrayType.getDimensions() < possibleSupertypeAsArrayType.getDimensions()) {
            return false;
        }
        Type possibleSupertypeBasicType = possibleSupertypeAsArrayType.getBasicType();
        if (!(possibleSupertypeBasicType instanceof ObjectType)) {
            return false;
        }
        Type typeBasicType = typeAsArrayType.getBasicType();

        // If dimensions differ, see if element types are compatible.
        if (typeAsArrayType.getDimensions() > possibleSupertypeAsArrayType.getDimensions()) {
            return isSubtype(
                    new ArrayType(typeBasicType, typeAsArrayType.getDimensions()
                            - possibleSupertypeAsArrayType.getDimensions()), (ObjectType) possibleSupertypeBasicType);
        }

        // type's base type must be a subtype of possibleSupertype's base
        // type.
        // Note that neither base type can be a non-ObjectType if we are to
        // answer yes.

        if (!(typeBasicType instanceof ObjectType)) {
            return false;
        }

        return isSubtype((ObjectType) typeBasicType, (ObjectType) possibleSupertypeBasicType);
    }

    // OK, we've exhausted the possibilities now
    return false;
}
 
Example #17
Source File: Hierarchy.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Resolve possible instance method call targets.
 *
 * @param receiverType
 *            type of the receiver object
 * @param invokeInstruction
 *            the InvokeInstruction
 * @param cpg
 *            the ConstantPoolGen
 * @param receiverTypeIsExact
 *            if true, the receiver type is known exactly, which should
 *            allow a precise result
 * @return Set of methods which might be called
 * @throws ClassNotFoundException
 */
public static Set<JavaClassAndMethod> resolveMethodCallTargets(ReferenceType receiverType,
        InvokeInstruction invokeInstruction, ConstantPoolGen cpg, boolean receiverTypeIsExact) throws ClassNotFoundException {
    HashSet<JavaClassAndMethod> result = new HashSet<>();

    if (invokeInstruction.getOpcode() == Const.INVOKESTATIC) {
        throw new IllegalArgumentException();
    }

    String methodName = invokeInstruction.getName(cpg);
    String methodSig = invokeInstruction.getSignature(cpg);

    // Array method calls aren't virtual.
    // They should just resolve to Object methods.
    if (receiverType instanceof ArrayType) {
        JavaClass javaLangObject = AnalysisContext.currentAnalysisContext().lookupClass(Values.DOTTED_JAVA_LANG_OBJECT);
        JavaClassAndMethod classAndMethod = findMethod(javaLangObject, methodName, methodSig, INSTANCE_METHOD);
        if (classAndMethod != null) {
            result.add(classAndMethod);
        }
        return result;
    }

    if (receiverType instanceof NullType) {
        return Collections.<JavaClassAndMethod>emptySet();
    }
    AnalysisContext analysisContext = AnalysisContext.currentAnalysisContext();

    // Get the receiver class.
    String receiverClassName = ((ObjectType) receiverType).getClassName();
    JavaClass receiverClass = analysisContext.lookupClass(receiverClassName);
    ClassDescriptor receiverDesc = DescriptorFactory.createClassDescriptorFromDottedClassName(receiverClassName);

    // Figure out the upper bound for the method.
    // This is what will be called if this is not a virtual call site.
    JavaClassAndMethod upperBound = findMethod(receiverClass, methodName, methodSig, CONCRETE_METHOD);
    if (upperBound == null) {
        upperBound = findInvocationLeastUpperBound(receiverClass, methodName, methodSig, CONCRETE_METHOD, false);
    }
    if (upperBound != null) {
        if (DEBUG_METHOD_LOOKUP) {
            System.out.println("Adding upper bound: "
                    + SignatureConverter.convertMethodSignature(upperBound.getJavaClass(), upperBound.getMethod()));
        }
        result.add(upperBound);
    }

    // Is this a virtual call site?
    boolean virtualCall = (invokeInstruction.getOpcode() == Const.INVOKEVIRTUAL || invokeInstruction.getOpcode() == Const.INVOKEINTERFACE)
            && (upperBound == null || !upperBound.getJavaClass().isFinal() && !upperBound.getMethod().isFinal())
            && !receiverTypeIsExact;

    if (virtualCall) {
        if (!Values.DOTTED_JAVA_LANG_OBJECT.equals(receiverClassName)) {

            // This is a true virtual call: assume that any concrete
            // subtype method may be called.
            Set<ClassDescriptor> subTypeSet = analysisContext.getSubtypes2().getSubtypes(receiverDesc);
            for (ClassDescriptor subtype : subTypeSet) {
                XMethod concreteSubtypeMethod = findMethod(subtype, methodName, methodSig, false);
                if (concreteSubtypeMethod != null && (concreteSubtypeMethod.getAccessFlags() & Const.ACC_ABSTRACT) == 0) {
                    result.add(new JavaClassAndMethod(concreteSubtypeMethod));
                }
            }
            if (false && subTypeSet.size() > 500) {
                new RuntimeException(receiverClassName + " has " + subTypeSet.size() + " subclasses, " + result.size()
                        + " of which implement " + methodName + methodSig + " " + invokeInstruction)
                                .printStackTrace(System.out);
            }

        }
    }
    return result;
}
 
Example #18
Source File: GenericUtilities.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
public static String asString(ArrayType atype) {
    Type obj = atype.getBasicType();
    String result = GenericUtilities.getString(obj);
    return result + Util.repeat("[]", atype.getDimensions());
}