//Tested with BCEL-5.1 //http://jakarta.apache.org/builds/jakarta-bcel/release/v5.1/ package com.puppycrawl.tools.checkstyle.bcel.classfile; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.apache.bcel.Repository; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.Method; import org.apache.bcel.generic.Type; import com.puppycrawl.tools.checkstyle.bcel.generic.InvokeReference; import com.puppycrawl.tools.checkstyle.bcel.generic.Utils; /** * Contains the definition of a Method and its references. * @author Rick Giles */ public class MethodDefinition extends FieldOrMethodDefinition { /** the references to the Method */ private Set mReferences = new HashSet(); /** * Creates a <code>MethodDefinition</code> for a Method. * @param aMethod the Method. */ public MethodDefinition(Method aMethod) { super(aMethod); } /** * Gets the references to the Method. * @return the references to the Method. */ public Set getReferences() { return mReferences; } /** * Determines the number of references to the Method. * @return the number of references to the Method. */ public int getReferenceCount() { return mReferences.size(); } /** * Returns the Method for this definition. * @return the Method for this definition. */ public Method getMethod() { return (Method) getFieldOrMethod(); } /** * Adds a reference to the Method. * @param aRef the reference. */ public void addReference(InvokeReference aRef) { mReferences.add(aRef); } /** * Gets the Types of the Method's arguments. * @return the argument Types. */ public Type[] getArgumentTypes() { return getMethod().getArgumentTypes(); } /** * Determines whether a Method is compatible with the * Method of this definition. * @param aMethod the Method to check. * @return true if aMethod is compatible with the Method * of this definition. */ public boolean isCompatible(Method aMethod) { return isCompatible(aMethod.getName(), aMethod.getArgumentTypes()); } /** * Determines whether a MethodDefinition is compatible with the * Method of this definition. * @param aMethodDef the Method definition to check. * @return true if aMethod is compatible with the Method * of this definition. */ public boolean isCompatible(MethodDefinition aMethodDef) { return isCompatible(aMethodDef.getMethod()); } /** * Determines whether the Method of a MethodDefinition is as narrow * as the method for this definition. * Precondition: the method for this has the same name and the same * number of arguments as the Method for the given MethodDefinition. * @param aMethodDef the MethodDefinition to check. * @return true if the Method of aMethodDef is as narrow * as the method for this definition. */ public boolean isAsNarrow(MethodDefinition aMethodDef) { return aMethodDef.isCompatible(this); // final Type[] types1 = getArgumentTypes(); // final Type[] types2 = aMethodDef.getArgumentTypes(); // for (int i = 0; i < types2.length; i++) { // if (!Utils.isCompatible(types1[i], types2[i])) { // return false; // } // } // return true; } /** * Determines whether a method is compatible with the Method of * this definition. * @param aMethodName the name of the method to check. * @param aArgTypes the method argument types. * @return true if the method is compatible with the Method of * this definition. */ public boolean isCompatible(String aMethodName, Type[] aArgTypes) { // same name? if (!getName().equals(aMethodName)) { return false; } // compatible argument types? final Type[] methodTypes = getArgumentTypes(); if (methodTypes.length != aArgTypes.length) { return false; } for (int i = 0; i < aArgTypes.length; i++) { if (!Utils.isCompatible(aArgTypes[i], methodTypes[i])) { return false; } } return true; } /** * Determine whether this method definition has a reference from a class or * a superclass. * @param aJavaClass the JavaClass to check against. * @return true if there is a reference to this method definition from a * aJavaClass or a superclass of aJavaClass. */ public boolean hasReference(JavaClass aJavaClass) { final Iterator it = getReferences().iterator(); while (it.hasNext()) { final InvokeReference invokeRef = (InvokeReference) it.next(); final String invokeClassName = invokeRef.getClassName(); if (Repository.instanceOf(aJavaClass, invokeClassName)) { return true; } } return false; } }