Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   * fb-contrib - Auxiliary detectors for Java programs
   * Copyright (C) 2005-2014 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
  * 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  org.apache.bcel.classfile.Code;
 import  org.apache.bcel.classfile.Method;
 import  org.apache.bcel.generic.Type;
looks for methods that make a recursive call to itself as the last statement in the method. This tail recursion could be converted into a simple loop which would improve the performance and stack requirements.
 public class TailRecursion extends BytecodeScanningDetector 
 	public static final int TAILRECURSIONFUDGE = 6;
 	private OpcodeStack stack;
 	private int trPCPos;
 	private boolean possibleTailRecursion;
 	private boolean isStatic;

constructs a TR detector given the reporter to report bugs on

bugReporter the sync of bug reports
 	public TailRecursion(BugReporter bugReporter) {
 		this. = bugReporter;

implements the visitor to create and clear the stack

classContext the context object of the currently parsed class
 	public void visitClassContext(ClassContext classContext) {
 		try {
 			 = new OpcodeStack();
 		} finally {
 			 = null;
implements the visitor to figure the pc where the method call must occur depending on whether the method returns a value, or not.

obj the context object of the currently parsed method
 	public void visitMethod(Method obj) {
 		Code c = obj.getCode();
 		if (c != null) {
 			byte[] opcodes = c.getCode();
 			if (opcodes != null) {
 				 = c.getCode().length - 1;
 				if (!obj.getSignature().endsWith("V")) {
 					 -= 1;
 				 = obj.isStatic();

implements the visitor to find methods that employ tail recursion

seen the opcode of the currently parsed instruction
	public void sawOpcode(int seen) {
		try {
			if (seen == INVOKEVIRTUAL) {
				boolean isRecursion = (getMethodName().equals(getNameConstantOperand()))
								   && (getMethodSig().equals(getSigConstantOperand()))
								   && (getClassName().equals(getClassConstantOperand()));
				if (isRecursion && !) {
					int numParms = Type.getArgumentTypes(getMethodSig()).length;
					if (.getStackDepth() > numParms) {
						OpcodeStack.Item itm = .getStackItem(numParms);
						isRecursion = (itm.getRegisterNumber() == 0);
				if (isRecursion &&  && (getPC() >= )) {
					.reportBug(new BugInstance(this"TR_TAIL_RECURSION", NORMAL_PRIORITY)
finally {
New to GrepCode? Check out our FAQ X