diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/ReferenceVisitor.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/ReferenceVisitor.java index ab6f11401..f2e9b7f4f 100644 --- a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/ReferenceVisitor.java +++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/ReferenceVisitor.java @@ -3,6 +3,7 @@ package com.puppycrawl.tools.checkstyle.bcel; +import java.util.HashSet; import java.util.Set; import org.apache.bcel.classfile.ConstantPool; @@ -16,6 +17,7 @@ import org.apache.bcel.generic.INVOKEVIRTUAL; import org.apache.bcel.generic.PUTFIELD; import org.apache.bcel.generic.PUTSTATIC; +import com.puppycrawl.tools.checkstyle.api.Scope; import com.puppycrawl.tools.checkstyle.bcel.classfile.JavaClassDefinition; import com.puppycrawl.tools.checkstyle.bcel.classfile.ReferenceDAO; import com.puppycrawl.tools.checkstyle.bcel.generic.FieldReference; @@ -29,10 +31,17 @@ import com.puppycrawl.tools.checkstyle.bcel.generic.PUTSTATICReference; * Records references during a deep parse tree traversal. * @author Rick Giles */ -public final class ReferenceVisitor extends EmptyDeepVisitor { +public final class ReferenceVisitor extends EmptyDeepVisitor +{ /** singleton */ private static ReferenceVisitor sInstance = new ReferenceVisitor(); + /** scope for checking field references */ + private Set mFieldScopes = new HashSet(); + + /** scope for checking method references */ + private Set mMethodScopes = new HashSet(); + /** maps a JavaClass to a JavaClassDefinition */ private ReferenceDAO mReferenceDAO; @@ -45,60 +54,71 @@ public final class ReferenceVisitor extends EmptyDeepVisitor { * @author Rick Giles * @version 18-Jun-2003 */ - private class GenericVisitor extends org.apache.bcel.generic.EmptyVisitor { + private class GenericVisitor extends org.apache.bcel.generic.EmptyVisitor + { /** @see org.apache.bcel.generic.Visitor */ - public void visitINVOKESPECIAL(INVOKESPECIAL aINVOKESPECIAL) { + public void visitINVOKESPECIAL(INVOKESPECIAL aINVOKESPECIAL) + { addInvokeReference( new InvokeReference(aINVOKESPECIAL, mCurrentPoolGen)); } /** @see org.apache.bcel.generic.Visitor */ - public void visitINVOKESTATIC(INVOKESTATIC aINVOKESTATIC) { + public void visitINVOKESTATIC(INVOKESTATIC aINVOKESTATIC) + { addInvokeReference( new InvokeReference(aINVOKESTATIC, mCurrentPoolGen)); } /** @see org.apache.bcel.generic.Visitor */ - public void visitINVOKEVIRTUAL(INVOKEVIRTUAL aINVOKEVIRTUAL) { + public void visitINVOKEVIRTUAL(INVOKEVIRTUAL aINVOKEVIRTUAL) + { addInvokeReference( new InvokeReference(aINVOKEVIRTUAL, mCurrentPoolGen)); } /** @see org.apache.bcel.generic.Visitor */ - public void visitGETSTATIC(GETSTATIC aGETSTATIC) { + public void visitGETSTATIC(GETSTATIC aGETSTATIC) + { addFieldReference( new GETSTATICReference(aGETSTATIC, mCurrentPoolGen)); } /** @see org.apache.bcel.generic.Visitor */ - public void visitGETFIELD(GETFIELD aGETFIELD) { + public void visitGETFIELD(GETFIELD aGETFIELD) + { addFieldReference( new GETFIELDReference(aGETFIELD, mCurrentPoolGen)); } /** @see org.apache.bcel.generic.Visitor */ - public void visitPUTSTATIC(PUTSTATIC aPUTSTATIC) { + public void visitPUTSTATIC(PUTSTATIC aPUTSTATIC) + { addFieldReference( new PUTSTATICReference(aPUTSTATIC, mCurrentPoolGen)); } /** @see org.apache.bcel.generic.Visitor */ - public void visitPUTFIELD(PUTFIELD aPUTFIELD) { + public void visitPUTFIELD(PUTFIELD aPUTFIELD) + { addFieldReference( new PUTFIELDReference(aPUTFIELD, mCurrentPoolGen)); } } /** prevent client construction */ - private ReferenceVisitor() { + private ReferenceVisitor() + { setGenericVisitor(new GenericVisitor()); + addFieldScope(Scope.PRIVATE); } /** * Returns the singleton ReferencesVisitor * @return the singleton */ - public static ReferenceVisitor getInstance() { + public static ReferenceVisitor getInstance() + { return sInstance; } @@ -106,7 +126,8 @@ public final class ReferenceVisitor extends EmptyDeepVisitor { * Adds an invoke reference to the reference DAO. * @param aReference the reference. */ - private void addInvokeReference(InvokeReference aReference) { + private void addInvokeReference(InvokeReference aReference) + { getReferenceDAO().addInvokeReference(aReference); } @@ -114,25 +135,30 @@ public final class ReferenceVisitor extends EmptyDeepVisitor { * Adds an field reference to the reference DAO. * @param aReference the reference. */ - private void addFieldReference(FieldReference aReference) { + private void addFieldReference(FieldReference aReference) + { getReferenceDAO().addFieldReference(aReference); } /** @see com.puppycrawl.tools.checkstyle.bcel.IDeepVisitor */ - public void visitSet(Set aJavaClasses) { - mReferenceDAO = new ReferenceDAO(aJavaClasses); + public void visitSet(Set aJavaClasses) + { + mReferenceDAO = + new ReferenceDAO(aJavaClasses, mFieldScopes, mMethodScopes); } /** * Gets the reference DAO. * @return the reference DAO. */ - public ReferenceDAO getReferenceDAO() { + public ReferenceDAO getReferenceDAO() + { return mReferenceDAO; } /** @see com.puppycrawl.tools.checkstyle.bcel.IDeepVisitor */ - public void visitObject(Object aObject) { + public void visitObject(Object aObject) + { final JavaClass javaClass = (JavaClass) aObject; final ConstantPool pool = javaClass.getConstantPool(); mCurrentPoolGen = new ConstantPoolGen(pool); @@ -143,7 +169,26 @@ public final class ReferenceVisitor extends EmptyDeepVisitor { * @param aJavaClass the JavaClass. * @return the JavaClassDefinition for aJavaClass. */ - public JavaClassDefinition findJavaClassDef(JavaClass aJavaClass) { + public JavaClassDefinition findJavaClassDef(JavaClass aJavaClass) + { return getReferenceDAO().findJavaClassDef(aJavaClass); } + + /** + * Includes a scope in the scope for checking field references. + * @param aScope the scope to include. + */ + public void addFieldScope(Scope aScope) + { + mFieldScopes.add(aScope); + } + + /** + * Includes a scope in the scope for checking method references. + * @param aScope the scope to include. + */ + public void addMethodScope(Scope aScope) + { + mMethodScopes.add(aScope); + } } diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/AbstractReferenceCheck.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/AbstractReferenceCheck.java index df6f6560d..fb35aaeea 100644 --- a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/AbstractReferenceCheck.java +++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/AbstractReferenceCheck.java @@ -51,12 +51,12 @@ public abstract class AbstractReferenceCheck { mScope = Scope.getInstance(aScopeName); } - + /** - * Determines whether a class name and field or method should be ignored. - * @param aClassName the class name. - * @param aName the name. - * @return true if aClassName and aName should be ignored. + * Determines whether a class name, and field or method should be ignored. + * @param aClassName the class name to consider. + * @param aFieldOrMethod the field or method to consider. + * @return true if aClassName, and field or method should be ignored. */ protected boolean ignore(String aClassName, FieldOrMethod aFieldOrMethod) { @@ -65,7 +65,7 @@ public abstract class AbstractReferenceCheck || mIgnoreClassNameRegexp.match(aClassName) || mIgnoreNameRegexp.match(fieldOrMethodName)); } - + /** * Tests whether the scope of a field or method is compatible * with the scope of this check. References for compatible diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnreadFieldCheck.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnreadFieldCheck.java index ae341750c..a60f596c1 100644 --- a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnreadFieldCheck.java +++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnreadFieldCheck.java @@ -9,6 +9,8 @@ import java.util.Set; import org.apache.bcel.classfile.Field; import org.apache.bcel.classfile.JavaClass; +import com.puppycrawl.tools.checkstyle.api.Scope; +import com.puppycrawl.tools.checkstyle.bcel.ReferenceVisitor; import com.puppycrawl.tools.checkstyle.bcel.classfile.FieldDefinition; import com.puppycrawl.tools.checkstyle.bcel.classfile.JavaClassDefinition; @@ -19,6 +21,14 @@ import com.puppycrawl.tools.checkstyle.bcel.classfile.JavaClassDefinition; public class UnreadFieldCheck extends AbstractReferenceCheck { + /** @see AbstractReferenceCheck */ + public void setScope(String aFrom) + { + super.setScope(aFrom); + ((ReferenceVisitor) getVisitor()).addFieldScope( + Scope.getInstance(aFrom)); + } + /** @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor */ public void leaveSet(Set aJavaClasses) { diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnusedMethodCheck.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnusedMethodCheck.java index f432e0791..d42f355de 100644 --- a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnusedMethodCheck.java +++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/checks/UnusedMethodCheck.java @@ -9,6 +9,8 @@ import java.util.Set; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.Method; +import com.puppycrawl.tools.checkstyle.api.Scope; +import com.puppycrawl.tools.checkstyle.bcel.ReferenceVisitor; import com.puppycrawl.tools.checkstyle.bcel.classfile.JavaClassDefinition; import com.puppycrawl.tools.checkstyle.bcel.classfile.MethodDefinition; @@ -19,6 +21,14 @@ import com.puppycrawl.tools.checkstyle.bcel.classfile.MethodDefinition; public class UnusedMethodCheck extends AbstractReferenceCheck { + /** @see AbstractReferenceCheck */ + public void setScope(String aScopeName) + { + super.setScope(aScopeName); + ((ReferenceVisitor) getVisitor()).addMethodScope( + Scope.getInstance(aScopeName)); + } + /** @see com.puppycrawl.tools.checkstyle.bcel.IObjectSetVisitor */ public void leaveSet(Set aJavaClasses) { @@ -32,8 +42,7 @@ public class UnusedMethodCheck if (!classDef.hasReference(methodDefs[i], getReferenceDAO())) { final String methodName = methodDefs[i].getName(); final Method method = methodDefs[i].getMethod(); - if (!ignore(className, method)) - { + if (!ignore(className, method)) { log( 0, "unused.method", diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/JavaClassDefinition.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/JavaClassDefinition.java index 9d2b8ecb4..dc018bc81 100644 --- a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/JavaClassDefinition.java +++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/JavaClassDefinition.java @@ -4,7 +4,9 @@ package com.puppycrawl.tools.checkstyle.bcel.classfile; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import org.apache.bcel.Repository; import org.apache.bcel.classfile.Field; @@ -30,29 +32,46 @@ public class JavaClassDefinition private Map mFieldDefs; /** - * Creates a JavaClassDefinition from a JavaClass. + * Creates a JavaClassDefinition from a JavaClass. The fields and + * methods of the JavaClassDefinition are those whose scopes are + * in restricted sets of Scopes. * @param aJavaClass the JavaClass for the definition. + * @param aFieldScopes the restricted set of field scopes. + * @param aMethodScopes the restriced set of method scopes. */ - public JavaClassDefinition(JavaClass aJavaClass) + public JavaClassDefinition( + JavaClass aJavaClass, + Set aFieldScopes, + Set aMethodScopes) { mJavaClass = aJavaClass; - // store method definitions + // create method definitions, restricted by scope final Method[] methods = aJavaClass.getMethods(); + final Set methodSet = new HashSet(); mMethodDefs = new MethodDefinition[methods.length]; for (int i = 0; i < methods.length; i++) { - mMethodDefs[i] = new MethodDefinition(methods[i]); + if (Utils.inScope(methods[i], aMethodScopes)) { + methodSet.add(new MethodDefinition(methods[i])); + } } + mMethodDefs = + (MethodDefinition[]) methodSet.toArray( + new MethodDefinition[methodSet.size()]); - // store field definitions + // create field definitions, restricted by scope final Field[] fields = aJavaClass.getFields(); mFieldDefs = new HashMap(fields.length); for (int i = 0; i < fields.length; i++) { - mFieldDefs.put(fields[i].getName(), new FieldDefinition(fields[i])); + if (Utils.inScope(fields[i], aFieldScopes)) { + mFieldDefs.put( + fields[i].getName(), + new FieldDefinition(fields[i])); + } } } - /** + /** * Gets the JavaClass for this definition. * @return the JavaClass */ @@ -135,31 +154,31 @@ public class JavaClassDefinition public boolean hasReference( MethodDefinition aMethodDef, ReferenceDAO aReferenceDAO) - { - final String methodName = aMethodDef.getName(); - final Type[] argTypes = aMethodDef.getArgumentTypes(); - - // search the inheritance hierarchy - JavaClass currentJavaClass = getJavaClass(); - while (currentJavaClass != null) { - final JavaClassDefinition javaClassDef = - aReferenceDAO.findJavaClassDef(currentJavaClass); - if (javaClassDef != null) { - final MethodDefinition methodDef = - javaClassDef.findNarrowestMethod( - getJavaClass().getClassName(), - methodName, - argTypes); - if ((methodDef != null) + { + final String methodName = aMethodDef.getName(); + final Type[] argTypes = aMethodDef.getArgumentTypes(); + + // search the inheritance hierarchy + JavaClass currentJavaClass = getJavaClass(); + while (currentJavaClass != null) { + final JavaClassDefinition javaClassDef = + aReferenceDAO.findJavaClassDef(currentJavaClass); + if (javaClassDef != null) { + final MethodDefinition methodDef = + javaClassDef.findNarrowestMethod( + getJavaClass().getClassName(), + methodName, + argTypes); + if ((methodDef != null) && (methodDef.hasReference(getJavaClass()))) - { - return true; - } - } - currentJavaClass = currentJavaClass.getSuperClass(); - } - return false; - } + { + return true; + } + } + currentJavaClass = currentJavaClass.getSuperClass(); + } + return false; + } /** @see java.lang.Object#toString() */ public String toString() diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/ReferenceDAO.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/ReferenceDAO.java index 8db06dd37..f889c8684 100644 --- a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/ReferenceDAO.java +++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/ReferenceDAO.java @@ -21,25 +21,27 @@ import com.puppycrawl.tools.checkstyle.bcel.generic.InvokeReference; */ public class ReferenceDAO { - /** maps a JavaClass to a JavaClassDefinition */ - private Map mJavaClasses = null; - /** * Creates a ReferenceDAO from a set of JavaClasses. * @param aJavaClasses the set of JavaClasses for this DAO. + * @param aFieldScopes the scopes for field references. + * @param aMethodScopes the scopes for method references. */ - public ReferenceDAO(Set aJavaClasses) + public ReferenceDAO(Set aJavaClasses, Set aFieldScopes, Set aMethodScopes) { mJavaClasses = new HashMap(aJavaClasses.size()); final Iterator it = aJavaClasses.iterator(); while (it.hasNext()) { final JavaClass javaClass = (JavaClass) it.next(); final JavaClassDefinition javaClassDef = - new JavaClassDefinition(javaClass); + new JavaClassDefinition(javaClass, aFieldScopes, aMethodScopes); mJavaClasses.put(javaClass, javaClassDef); } } + /** maps a JavaClass to a JavaClassDefinition */ + private Map mJavaClasses = null; + /** * Finds the JavaClassDefinition for a given JavaClass. * @param aJavaClass the JavaClass. diff --git a/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/Utils.java b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/Utils.java new file mode 100644 index 000000000..9d61f0615 --- /dev/null +++ b/contrib/bcel/src/checkstyle/com/puppycrawl/tools/checkstyle/bcel/classfile/Utils.java @@ -0,0 +1,39 @@ +package com.puppycrawl.tools.checkstyle.bcel.classfile; + +import java.util.Set; + +import org.apache.bcel.classfile.FieldOrMethod; + +import com.puppycrawl.tools.checkstyle.api.Scope; + +/** + * Utility methods for BCEL classfile package + * @author Rick Giles + */ +public class Utils +{ + /** + * Determines whether the declared scope of a field or method is in + * a set of scopes. + * @param aFieldOrMethod the field or method to test. + * @param aScopes the set of scopes to test against. + * @return true if the declared scope of aFieldOrMethod is in aScopes. + */ + public static boolean inScope(FieldOrMethod aFieldOrMethod, Set aScopes) + { + if (aFieldOrMethod.isPrivate()) { + return (aScopes.contains(Scope.PRIVATE)); + } + else if (aFieldOrMethod.isProtected()) { + return (aScopes.contains(Scope.PROTECTED)); + } + else if (aFieldOrMethod.isPublic()) { + return (aScopes.contains(Scope.PUBLIC)); + } + else { + return (aScopes.contains(Scope.PACKAGE)); + } + } + + +}