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  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.ba.ClassContext;

looks for constructors that operate through side effects, specifically constructors that aren't assigned to any variable or field.
 
 public class SideEffectConstructor extends BytecodeScanningDetector {
 
 	private enum State {SAW_NOTHING, SAW_CTOR};
 	private final BugReporter bugReporter;
 	private OpcodeStack stack;
 	private State state;

constructs a SEC detector given the reporter to report bugs on

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

overrides the visitor to set up and tear down the opcode stack

Parameters:
classContext the context object of the currently parsed class
 
 	public void visitClassContext(ClassContext classContext) {
 		try {
 			 = new OpcodeStack();
 			super.visitClassContext(classContext);
 		} finally {
 			 = null;
 		}
 	}
overrides the visitor to reset the state and reset the opcode stack

Parameters:
obj the context object of the currently parsed code
 
 	public void visitCode(Code obj) {
 		.resetForMethodEntry(this);
 		super.visitCode(obj);
 	}

overrides the visitor to look for constructors who's value is popped off the stack, and not assigned before the pop of the value, or if a return is issued with that object still on the stack.

Parameters:
seen the opcode of the currently parse opcode
 
 	public void sawOpcode(int seen) {
 		int pc = 0;
 		try {
 			switch () {
 				case :
 					if (seen == INVOKESPECIAL) {
 						if ("<init>".equals(name)) {
 							int numArgs = Type.getArgumentTypes(sig).length;
 							if (.getStackDepth() > numArgs) {
 								OpcodeStack.Item caller = .getStackItem(numArgs);
 								if (caller.getRegisterNumber() != 0) {
									pc = getPC();
								}
							}
						}
else if (seen == RETURN) {
						int depth = .getStackDepth();
						for (int i = 0; i < depthi++) {
							OpcodeStack.Item item = .getStackItem(i);
							Integer secPC = (Integer)item.getUserValue();
							if (secPC != null) {
								.reportBug(new BugInstance(this"SEC_SIDE_EFFECT_CONSTRUCTOR", NORMAL_PRIORITY)
								.addClass(this)
								.addMethod(this)
								.addSourceLine(thissecPC.intValue()));
								break;
							}
						}
					}
				break;
				case :
					if (seen == POP || seen == RETURN) {
						.reportBug(new BugInstance(this"SEC_SIDE_EFFECT_CONSTRUCTOR", NORMAL_PRIORITY)
															.addClass(this)
															.addMethod(this)
															.addSourceLine(this));
					}
				break;
			}
finally {
			TernaryPatcher.pre(seen);
			.sawOpcode(thisseen);
			TernaryPatcher.post(seen);
			if (pc != 0) {
				if (.getStackDepth() > 0) {
					OpcodeStack.Item item = .getStackItem(0);
					item.setUserValue(Integer.valueOf(pc));
				}
			}
		}
	}
New to GrepCode? Check out our FAQ X