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.Set;
 
 import  org.apache.bcel.classfile.Code;
 import  org.apache.bcel.generic.Type;
 
 
 import  edu.umd.cs.findbugs.BugInstance;
 import  edu.umd.cs.findbugs.BugReporter;
 import  edu.umd.cs.findbugs.BytecodeScanningDetector;
 import  edu.umd.cs.findbugs.OpcodeStack;
 import  edu.umd.cs.findbugs.OpcodeStack.CustomUserValue;
 import  edu.umd.cs.findbugs.ba.ClassContext;
 import  edu.umd.cs.findbugs.ba.XField;

looks for method calls that passes the same argument to two different parameters of the same method. It doesn't report method calls where the arguments are constants.
 
 @CustomUserValue
 public class StutteredMethodArguments extends BytecodeScanningDetector {
 	private static Set<StringignorableSignatures = new HashSet<String>();
 	static {
 		.add("java/util/Map:put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
 	}
 	private final BugReporter bugReporter;
 	private OpcodeStack stack;
constructs a SMA detector given the reporter to report bugs on.

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

overrides the visitor to create the opcode stack

Parameters:
classContext the context object of the currently parsed class
 
 	public void visitClassContext(ClassContext classContext)
 	{
 		try {
 			 = new OpcodeStack();
 			 = classContext.getJavaClass().getPackageName();
 			super.visitClassContext(classContext);
 		} finally {
 			 = null;
 		}
 	}

overrides the visitor to reset the stack object

Parameters:
obj the context object of the currently parsed code block
 
 	public void visitCode(Code obj) {
 		try {
 			.resetForMethodEntry(this);
 			 = getMethod().getName();
 			super.visitCode(obj);
 		} finally {
 		}
 		
 	}

overrides the visitor to look for method calls that pass the same value for two different arguments

Parameters:
seen the currently parsed op code
	public void sawOpcode(int seen) {
		String fieldSource = null;
		try {
	        .precomputation(this);
	        
			switch (seen) {
				case INVOKEVIRTUAL:
				case INVOKESTATIC:
				case INVOKEINTERFACE:
				case INVOKESPECIAL:
					String packageName;
					int slashPos = clsName.lastIndexOf('/');
					if (slashPos >= 0)
					{
						packageName = clsName.substring(0, slashPos);
					}
					else
					{
						packageName = "";
					}
					if (SignatureUtils.similarPackages(packageName, 2)) {
						String methodName = getNameConstantOperand();
						String signature = getSigConstantOperand();
						String methodInfo = clsName + ":" + methodName + signature;
						if ((!.equals(methodName)) && !.contains(methodInfo)) {
							Type[] parms = Type.getArgumentTypes(signature);
							if (parms.length > 1) {
								if (.getStackDepth() > parms.length) {
									if (duplicateArguments(parms)) {
										.reportBug(new BugInstance(this"SMA_STUTTERED_METHOD_ARGUMENTS", NORMAL_PRIORITY)
												   .addClass(this)
												   .addMethod(this)
												   .addSourceLine(this));
									}
								}
							}
						}
					}
				break;
				case GETFIELD:
				case GETSTATIC:
					if (.getStackDepth() > 0) {
						OpcodeStack.Item item = .getStackItem(0);
						int reg = item.getRegisterNumber();
						if (reg >= 0)
						{
							fieldSource = String.valueOf(reg);
						}
						else {
							XField f = item.getXField();
							if (f != null) {
								fieldSource = f.getClassName() + ':' + f.getName();
else {
								fieldSource = "";
							}
						}
					}
				break;
			}
finally {
			TernaryPatcher.pre(seen);
			.sawOpcode(thisseen);
			TernaryPatcher.post(seen);
			if (fieldSource != null) {
				if (.getStackDepth() > 0) {
					OpcodeStack.Item item = .getStackItem(0);
					item.setUserValue(fieldSource);
				}
			}
		}
	}

looks for duplicate arguments that are not constants

Parameters:
opStack the stack to look thru
parms the arguments to the method being called
Returns:
if there are duplicates
	private boolean duplicateArguments(OpcodeStack opStack, Type[] parms)
	{
		Set<Stringargs = new HashSet<String>();
		for (int i = 0; i < parms.length; i++) {
			OpcodeStack.Item item = opStack.getStackItem(i);
			String signature = item.getSignature();
			if (signature.startsWith("L") && !signature.startsWith("Ljava/lang/") && (item.getConstant() == null)) {
				String arg = null;
				int reg = item.getRegisterNumber();
				if (reg >= 0) {
					arg = String.valueOf(reg);
else {
					XField f = item.getXField();
					if (f != null) {
						String fieldSource = (String)item.getUserValue();
						if (fieldSource == null)
						{
							fieldSource = "";
						}
						arg = fieldSource + '|' + f.getClassName() + ':' + f.getName();
					}
				}
				if (arg != null) {
					arg += "--" + parms[i].getSignature();
					if (args.contains(arg))
					{
						return true;
					}
					args.add(arg);
				}
			}
		}
		return false;
	}
New to GrepCode? Check out our FAQ X