Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * fb-contrib - Auxiliary detectors for Java programs
   * Copyright (C) 2005-2013 Dave Brosius
   * 
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   * 
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  * 
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 package com.mebigfatguy.fbcontrib.detect;
 
 import java.util.Map;
 
 import  org.apache.bcel.classfile.Code;
 import  org.apache.bcel.classfile.ConstantClass;
 import  org.apache.bcel.classfile.JavaClass;
 import  org.apache.bcel.classfile.Method;
 import  org.apache.bcel.generic.ConstantPoolGen;
 import  org.apache.bcel.generic.FieldInstruction;
 import  org.apache.bcel.generic.Instruction;
 import  org.apache.bcel.generic.InstructionHandle;
 import  org.apache.bcel.generic.InstructionList;
 import  org.apache.bcel.generic.InvokeInstruction;
 import  org.apache.bcel.generic.LDC;
 import  org.apache.bcel.generic.ReferenceType;
 import  org.apache.bcel.generic.Type;
 
 import  edu.umd.cs.findbugs.BugInstance;
 import  edu.umd.cs.findbugs.BugReporter;
 import  edu.umd.cs.findbugs.Detector;
 import  edu.umd.cs.findbugs.ba.ClassContext;
 import  edu.umd.cs.findbugs.visitclass.DismantleBytecode;

Looks for methods that are direct copies of the implementation in the super class
 
 public class CopiedOverriddenMethod extends DismantleBytecode implements Detector
 {
 	private final BugReporter bugReporter;
 	private Map<String, Code> superclassCode;
 	private ClassContext classContext;
 	private String curMethodInfo;
 	private ConstantPoolGen childPoolGenparentPoolGen;

constructs a COM detector given the reporter to report bugs on

Parameters:
bugReporter the sync of bug reports
 
 	public CopiedOverriddenMethod(BugReporter bugReporter) {
 		this. = bugReporter;
 	}

overrides the visitor to accept classes derived from non java.lang.Object classes.

Parameters:
clsContext the context object of the currently parsed class
 
 	public void visitClassContext(ClassContext clsContext) {
 		try {
 			JavaClass cls = clsContext.getJavaClass();
 			String superName = cls.getSuperclassName();
 			if (!"java.lang.Object".equals(superName)) {
 				this. = clsContext;
 				 = new HashMap<String, Code>();
 				JavaClass superCls = cls.getSuperClass();
 				 = new ConstantPoolGen(cls.getConstantPool());
 				 = new ConstantPoolGen(superCls.getConstantPool());
 				Method[] methods = superCls.getMethods();
 				for (Method m : methods) {
 					String methodName = m.getName();
 					if ((m.isPublic() ||  m.isProtected())
 							&&  (!m.isAbstract())
 							&&  (!"<init>".equals(methodName) && !"<clinit>".equals(methodName))) {
 						String methodInfo = methodName + ":" + m.getSignature();
 						.put(methodInfom.getCode());
 					}
 				}
 				cls.accept(this);
 			}
 		} catch (ClassNotFoundException cnfe) {
 			.reportMissingClass(cnfe);
 		} finally {
 			 = null;
 			this. = null;
 			 = null;
 			 = null;
 		}
 	}

overrides the visitor to get the methodInfo

Parameters:
obj the method object for the currently parsed method
	public void visitMethod(Method obj) {
		 = obj.getName() + ":" + obj.getSignature();
	}

overrides the visitor to find code blocks of methods that are the same as its parents

Parameters:
obj the code object of the currently parsed method
	public void visitCode(Code obj) {
		Method m = getMethod();
		if (!m.isPublic() && !m.isProtected() && !m.isAbstract())
		{
			return;
		}
		Code superCode = .get();
		if (superCode != null) {
			if (codeEquals(objsuperCode)) {
				.reportBug(new BugInstance(this"COM_COPIED_OVERRIDDEN_METHOD", NORMAL_PRIORITY)
				.addClass(this)
				.addMethod(this)
				.addSourceLine(thisgetPC()));
			}
		}
	}

compares two code blocks to see if they are equal with regard to instructions and field accesses

Parameters:
child the first code block
parent the second code block
Returns:
whether the code blocks are the same
	@SuppressWarnings("deprecation")
	public boolean codeEquals(Code child, Code parent) {
		byte[] childBytes = child.getCode();
		byte[] parentBytes = parent.getCode();
		if ((childBytes == null) || (parentBytes == null))
		{
			return false;
		}
		if (childBytes.length != parentBytes.length)
		{
			return false;
		}
		InstructionHandle[] childihs = new InstructionList(childBytes).getInstructionHandles();
		InstructionHandle[] parentihs = new InstructionList(parentBytes).getInstructionHandles();
		if (childihs.length != parentihs.length)
		{
			return false;
		}
		for (int i = 0; i < childihs.length; i++) {
			InstructionHandle childih = childihs[i];
			InstructionHandle parentih = parentihs[i];
			Instruction childin = childih.getInstruction();
			Instruction parentin = parentih.getInstruction();
			if (!childin.getName().equals(parentin.getName())) {
				return false;
			}
			if (childin instanceof FieldInstruction) {
				String childFName = ((FieldInstruction) childin).getFieldName();
				String parentFName = ((FieldInstruction) parentin).getFieldName();
				if (!childFName.equals(parentFName)) {
					return false;
				}
				String childFSig = ((FieldInstruction) childin).getSignature();
				String parentFSig = ((FieldInstruction) parentin).getSignature();
				if (!childFSig.equals(parentFSig)) {
					return false;
				}
				if (childFSig.charAt(0) == 'L') {
					ReferenceType childRefType = ((FieldInstruction) childin).getReferenceType();
					ReferenceType parentRefType = ((FieldInstruction) parentin).getReferenceType();
					if (!childRefType.getSignature().equals(parentRefType.getSignature())) {
						return false;
					}
				}
else if (childin instanceof InvokeInstruction) {
				String childClassName = ((InvokeInstruction) childin).getClassName();
				String parentClassName = ((InvokeInstruction) parentin).getClassName();
				if (!childClassName.equals(parentClassName)) {
					return false;
				}
				String childMethodName = ((InvokeInstruction) childin).getMethodName();
				String parentMethodName = ((InvokeInstruction) parentin).getMethodName();
				if (!childMethodName.equals(parentMethodName))
				{
					return false;
				}
				String childSignature = ((InvokeInstruction) childin).getSignature();
				String parentSignature = ((InvokeInstruction) parentin).getSignature();
				if (!childSignature.equals(parentSignature))
				{
					return false;
				}
else if (childin instanceof LDC) {
				Type childType = ((LDC) childin).getType();
				Type parentType = ((LDC) parentin).getType();
				if (!childType.equals(parentType)) {
					return false;
				}
				Object childValue = ((LDC) childin).getValue();
				Object parentValue = ((LDC) parentin).getValue();
				if (childValue instanceof ConstantClass) {
					ConstantClass childClass = (ConstantClass)childValue;
					ConstantClass parentClass = (ConstantClass)parentValue;
					if (!childClass.getBytes(.getConstantPool()).equals(parentClass.getBytes(.getConstantPool()))) {
						return false;
					}
else if (!childValue.equals(parentValue)) {
					return false;
				}
				//TODO: Other Constant types
else {
				if (!childin.equals(parentin)) {
					return false;
				}
			}
		}
		return true;
	}

implements the detector with an empty implementation
	public void report() {
	}
New to GrepCode? Check out our FAQ X